poi文本替换
- word文档中添加字段
${字段名}
2. 创建文件副本,类型变更为zip格式
从zip的/word
目录中取出document.xml
文件
3. jar包导入
1 | <!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> |
- 代码需要的zip工具类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47/**
* 根据模板生成docx文件
* @param wordCommonDto 数据
* @param fileName 文件名
* @throws IOException
* @throws TemplateException
*/
public void makeWordByXcode(WordCommonDto wordCommonDto,String fileName) throws IOException, TemplateException {
/** 初始化配置文件 **/
Configuration configuration = new Configuration();
String fileDirectory = basePath+wordCommonDto.getWordType()+"/";
/** 加载文件 **/
configuration.setDirectoryForTemplateLoading(new File(fileDirectory));
/** 加载模板 **/
Template template = configuration.getTemplate("document.xml");
/** 准备数据 **/
Map<String,String> dataMap = new HashMap<String, String>();
/** 将数据映射为实体类后转为json格式,再转为map 避免字段值为null**/
// dataMap.put("phone","1");
// dataMap.put("year","2");
// dataMap.put("month","3");
// dataMap.put("day","4");
String str = JSONObject.toJSONString(wordCommonDto, SerializerFeature.WriteNullStringAsEmpty);
dataMap = JSONObject.parseObject(str,Map.class);
log.info(dataMap.toString());
/** 指定输出word文件的路径 **/
String outFilePath = outPath+fileName+".xml";
File docFile = new File(outFilePath);
FileOutputStream fos = new FileOutputStream(docFile);
Writer out = new BufferedWriter(new OutputStreamWriter(fos),10240);
template.process(dataMap,out);
if(out != null){
out.close();
}
try {
ZipInputStream zipInputStream = ZipUtils.wrapZipInputStream(new FileInputStream(new File(fileDirectory+wordCommonDto.getWordType()+".zip")));
ZipOutputStream zipOutputStream = ZipUtils.wrapZipOutputStream(new FileOutputStream(new File(outPath+fileName+".docx")));
String itemname = "word/document.xml";
ZipUtils.replaceItem(zipInputStream, zipOutputStream, itemname, new FileInputStream(new File(outPath+fileName+".xml")));
log.info("success");
} catch (Exception e) {
log.info(e.toString());
}
FileUtil.deleteFile(outPath+fileName+".xml");
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ZipUtils {
/**
* 替换某个 item,
* @param zipInputStream zip文件的zip输入流
* @param zipOutputStream 输出的zip输出流
* @param itemName 要替换的 item 名称
* @param itemInputStream 要替换的 item 的内容输入流
*/
public static void replaceItem(ZipInputStream zipInputStream,
ZipOutputStream zipOutputStream,
String itemName,
InputStream itemInputStream
){
//
if(null == zipInputStream){return;}
if(null == zipOutputStream){return;}
if(null == itemName){return;}
if(null == itemInputStream){return;}
//
ZipEntry entryIn;
try {
while((entryIn = zipInputStream.getNextEntry())!=null)
{
String entryName = entryIn.getName();
ZipEntry entryOut = new ZipEntry(entryName);
// 只使用 name
zipOutputStream.putNextEntry(entryOut);
// 缓冲区
byte [] buf = new byte[8*1024];
int len;
if(entryName.equals(itemName)){
// 使用替换流
while((len = (itemInputStream.read(buf))) > 0) {
zipOutputStream.write(buf, 0, len);
}
} else {
// 输出普通Zip流
while((len = (zipInputStream.read(buf))) > 0) {
zipOutputStream.write(buf, 0, len);
}
}
// 关闭此 entry
zipOutputStream.closeEntry();
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//e.printStackTrace();
close(itemInputStream);
close(zipInputStream);
close(zipOutputStream);
}
}
/**
* 包装输入流
*/
public static ZipInputStream wrapZipInputStream(InputStream inputStream){
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
return zipInputStream;
}
/**
* 包装输出流
*/
public static ZipOutputStream wrapZipOutputStream(OutputStream outputStream){
ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
return zipOutputStream;
}
private static void close(InputStream inputStream){
if (null != inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void close(OutputStream outputStream){
if (null != outputStream){
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
图片替换
代码实现
1 | /** |
word文档转pdf
jar包引入
org.apache.poi.xwpf.converter.core
包中引用了poi相关的jar包,根据实际情况修改相关依赖
1 | <dependency> |
代码实现
1 | public String makePdfByXcode(String fileName){ |
出现的问题
无法读取文档中字符
打开document.xml
检查需替换的字符格式,一个单词可能存在多种格式,重新编写文档,确保格式一致
存在多张图片时图片错位
正常图片:
错位图片:
图片右键>其他布局选项:
布局:
linux中文空白
原因:linux缺少中文字符
将C:\Windows\Fonts
内的中文字库复制到服务器/usr/share/fonts
下
安装字体索引指令
yum install mkfontscale
建立字体索引信息,更新字体缓存mkfontscale && mkfontdir && fc-cache -fv
查看是否按照成功fc-list :lang=zh
重新启动服务,加载字体