前言
由于业务需求,要求开发一个工具类,需要对Word模板中的内容进行替换,并且支持插入图片、根据业务生成自定义表格,以及对处理后的文件增加水印,处理完的文件支持保存doc、docx、pdf格式
1、定义模板预览
2、生成效果预览
- 保存为.docx格式
- 保存为.pdf格式
3、重点来了上代码
- pom文件依赖
前提:需要引入包 Spire.Doc.jar 大家可以去Maven官网进行下载:
https://mvnrepository.com/artifact/e-iceblue/spire.doc.free/5.2.0 如果出现jar包无法从仓库拉取,可以看下这篇帖子
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/e-iceblue/spire.doc.free -->
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc.free</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version>
</dependency>
- Java代码
public static void main(String[] args) {
//文本数据
Map dataMap =new HashMap();
dataMap.put("fileNo", "88556");
dataMap.put("name", "阿里巴巴国际站");
dataMap.put("socialCreditCode", "91330100799655058B");
dataMap.put("regAddress", "杭州市余杭区文一西路969号");
dataMap.put("frName", "张勇");
dataMap.put("regCapital", "12000万");
String tempPath = "officefile/gernerTemplate.docx";//模板地址(当前地址为项目根节点,如果用本地地址可直接复制文件所在位置全路径即可)
String newTextFilePath = "officefile/gernerNewFile1.pdf";//生成文件地址
//图片数据
Map pictureMap=new HashMap();
pictureMap.put("localPicture", "http://file.static.fijo.com.cn/ZSZX/ZSJC/ECZC0004/png/5be7cfa8-4e8c-479d-9524-4ef01d9513c8.png");
pictureMap.put("urlPicture", "http://file.static.fijo.com.cn/SFTM/SFTM-XZFW/STFA0003/jpg/9fd2e553-b87b-4ec0-acd2-1adf2ce6c504.jpg");
String[] header = { "学号", "姓名", "性别", "班级", "成绩" };//表头
String watermarkText = "管理员";//水印名称
String positionParam = "table";//表格所在位置标签
//列表数据
String[][] data =
{
new String[]{"0105", "赵晓晓", "男", "1", "88"},
new String[]{"0106", "李雯雯", "女", "7", "92"},
new String[]{"0107", "陈聪聪", "女", "11", "91"},
new String[]{"0108", "王明明", "男", "4", "95"},
new String[]{"0109", "韩梅梅", "女", "5", "94"},
};
try {
//执行前先删除文件,以防止占用或覆盖情况
File dirFile=new File(newTextFilePath);
dirFile.delete();
//添加表格
addFileTable(tempPath,newTextFilePath,positionParam,header,data);
//替换内容
replaceFileDate(newTextFilePath,newTextFilePath,watermarkText,dataMap,pictureMap);
} catch (Exception e) {
e.printStackTrace();
}
}
- 创建表格方法
/**
* 创建表格
* @param fileCatalogue 文件所在目录
* @param newFilePath 生成新文件目录
* @param positionParam 表格所在位置
* @param header 列表表头
* @param tableArr 数据集
*/
public static void addFileTable(String fileCatalogue ,String newFilePath,String positionParam, String[] header, String[][] tableArr){
//创建一个Document对象
Document document = new Document(fileCatalogue);
//添加一个节点
Section section = document.getSections().get(0);
//获取表格所在节点
TextSelection textSelection = document.findString(positionParam, true, true);
//获取关键字符串所在段落的索引
TextRange range2 = textSelection.getAsOneRange();
Paragraph paragraph = range2.getOwnerParagraph();
Body body = paragraph.ownerTextBody();
int index = body.getChildObjects().indexOf(paragraph);
//添加表格
Table table = section.addTable(true);
//生成行(数据数组长度+表头) 列(表头长度)
table.resetCells(tableArr.length + 1, header.length);
//将第一行设置为表格标题
TableRow row = table.getRows().get(0);
row.isHeader(true);
row.setHeight(20);
row.setHeightType(TableRowHeightType.Exactly);
row.getRowFormat().setBackColor(Color.gray);
for (int i = 0; i < header.length; i++)
{
row.getCells().get(i).getCellFormat().setVerticalAlignment(VerticalAlignment.Middle);
Paragraph paragraphs = row.getCells().get(i).addParagraph();
paragraphs.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
TextRange txtRange = paragraphs.appendText(header[i]);
txtRange.getCharacterFormat().setBold(true);
}
//将数据添加到其余行
for (int r = 0; r < tableArr.length; r++)
{
TableRow dataRow = table.getRows().get(r + 1);
dataRow.setHeight(25);
dataRow.setHeightType(TableRowHeightType.Exactly);
dataRow.getRowFormat().setBackColor(Color.white);
for (int c = 0; c < tableArr[r].length; c++)
{
dataRow.getCells().get(c).getCellFormat().setVerticalAlignment(VerticalAlignment.Middle);
dataRow.getCells().get(c).addParagraph().appendText(tableArr[r][c]);
}
}
//设置单元格的背景颜色
for (int j = 1; j < table.getRows().getCount(); j++)
{
if (j % 2 == 0)
{
TableRow row2 = table.getRows().get(j);
for (int f = 0; f < row2.getCells().getCount(); f++)
{
row2.getCells().get(f).getCellFormat().setBackColor(new Color(173, 216, 230));
}
}
}
//移除段落,插入表格
body.getChildObjects().remove(paragraph);
body.getChildObjects().insert(index, table);
//保存结果文件
document.saveToFile(newFilePath, FileFormat.Docx_2013);
}
- 执行插入图片、替换内容方法
//执行插入图片、替换内容方法
@SneakyThrows
public static void replaceFileDate(String filePath, String newFilePath,String text, Map dataMap, Map pictureMap) throws FileNotFoundException {
//插入图片
if (null != pictureMap){
addFileRender(filePath,newFilePath,pictureMap);
}
//替换文件内容
replaceText(newFilePath,newFilePath,dataMap,text);
}
/**
* 在文件对应位置插入图片
* @param fileCatalogue 文件地址
* @param newFilePath 生成新文件地址
* @param pictureMap 图片数据
* @throws Exception
*/
public static void addFileRender(String fileCatalogue ,String newFilePath, Map pictureMap) throws Exception {
//构建内容
Map<String, Object> datas = new HashMap<String, Object>() {
{
//遍历图片数据
pictureMap.forEach((key,value) -> {
String filePath = String.valueOf(value);
String suffix = filePath.substring(filePath.lastIndexOf(".") );
//本地图片
// put("localPicture", new PictureRenderData(100, 120, "officefile/tom.png"));
//构建网络图片 设置宽高
put(String.valueOf(key), new PictureRenderData(100, 100, suffix, BytePictureUtils.getUrlByteArray(String.valueOf(value))));
});
}
};
//插入图片
XWPFTemplate template = XWPFTemplate.compile(fileCatalogue)
.render(datas);
FileOutputStream out = new FileOutputStream(newFilePath);
template.write(out);
out.flush();
out.close();
template.close();
}
- 替换文档中的文本以及添加水印
/**
* 替换文档中的制定文字
*
* @param filePath 文件存放全路径
* @param newFilePath 产生的新文件存放地址
* @param dataMap 要替换的内容(key为要替换的内容,value为要替换成的内容)
* @param text 水印内容
* @return
* @throws FileNotFoundException
*/
public static void replaceText(String filePath,String newFilePath, Map<String, String> dataMap,String text) throws FileNotFoundException {
Document doc = new Document(filePath);
//替换内容
for (Map.Entry<String, String> entry : dataMap.entrySet()) {
String k = entry.getKey();
String v = entry.getValue();
doc.replace(k, v, true, false);
}
//添加水印 艺术字并设置大小
ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text);
shape.setWidth(60);
shape.setHeight(20);
//设置艺术字文本内容、位置及样式
shape.setVerticalPosition(30);
shape.setHorizontalPosition(20);
shape.setRotation(315);
shape.getWordArt().setFontFamily("黑体");
shape.getWordArt().setText(text);
shape.setFillColor(new Color(128,128,128));
shape.setLineStyle(ShapeLineStyle.Single);
shape.setStrokeColor(new Color(192, 192, 192, 255));
shape.setStrokeWeight(1);
Section section;
HeaderFooter header;
for (int n = 0; n < doc.getSections().getCount(); n++) {
section = doc.getSections().get(n);
//获取section的页眉
header = section.getHeadersFooters().getHeader();
Paragraph paragraph;
if (header.getParagraphs().getCount() > 0) {
//如果页眉有段落,取它第一个段落
paragraph = header.getParagraphs().get(0);
} else {
//否则新增加一个段落到页眉
paragraph = header.addParagraph();
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
//复制艺术字并设置多行多列位置
shape = (ShapeObject) shape.deepClone();
shape.setVerticalPosition(50 + 150 * i);
shape.setHorizontalPosition(20 + 160 * j);
paragraph.getChildObjects().add(shape);
}
}
}
//删除文件
File dirFile=new File(newFilePath);
dirFile.delete();
//根据生成文件后缀,生成docx或者pdf
String suffix = newFilePath.substring(newFilePath.lastIndexOf(".") +1);
if (suffix.equals("doc")||suffix.equals("docx")){
doc.saveToFile(newFilePath, FileFormat.Docx);
}else if (suffix.equals("pdf")){
doc.saveToFile(newFilePath, FileFormat.PDF);
}
}
总结
以上主要完成了对java替换模板内容,以及增加表格、水印、保存其他格式做了方法的封装,并且已在项目中作为公共方法使用;
如果以上内容对小伙伴有帮助,请关注支持,如有疑问可私信我,欢迎指教!
创作不易如有打赏,感激不尽