Wrod 模板导出功能实现

一:准备Word模板

根据自身需求,准备响应的模板,并提取模板文件;

二:核心类

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/**
* Author: Rupert Tears
* Date: Created in 19:01 2022/11/20
* Description: Thought is already is late, exactly is the earliest time.
*/
public class GenerateDocxUtil {
private static Logger logger = LoggerFactory.getLogger(GenerateDocxUtil.class);
public static void freemarkerDocxTest(String rootPath, Map<String,Object> dataMap, String docxPath) throws Exception{
//配置freemarker模板
Configuration configuration = new Configuration();
String fileDirectory = rootPath;
configuration.setDirectoryForTemplateLoading(new File(fileDirectory));
String temName = "tem1.xml";
String docxZipPath = rootPath + "tem1.zip";
Template template = configuration.getTemplate(temName);

//通过模板生成的xml临时文件 方法结束后删除该临时文件
String outFilePath = rootPath + UUID.randomUUID().toString().replace("-","") + ".xml";
//指定输出word xml文件的路径
File docXmlFile = new File(outFilePath);
FileOutputStream fos = new FileOutputStream(docXmlFile);
Writer out = new BufferedWriter(new OutputStreamWriter(fos),10240);
template.process(dataMap,out);
if(out != null){
out.close();
}

//以下代码 主要用来加密已经生成的xml文件,把xml文件正式转换成加密的word文档
//包装输入流
ZipInputStream zipInputStream = wrapZipInputStream(new FileInputStream(new File(docxZipPath)));
//包装输出流
ZipOutputStream zipOutputStream = wrapZipOutputStream(new FileOutputStream(new File(docxPath)));
//正式加密替换成docx格式文档
List<String> itemNameList = new ArrayList<>();
itemNameList.add("word/document.xml");
//如果需要替换图片添加此行代码,"word/media/image1.png"为解压出来docx模板后,模板中对应图片的完整路径及名称,如果你添加的图片为jpg格式,那么图片名称会是"image1.jpg"或"image1.jpeg",各位自己视情况修改,如需替换多张图片就举一反三,往list插入多个元素,我相信你们可以理解的
// itemNameList.add("word/media/image1.png");

List<InputStream> itemInputStreamList = new ArrayList<>();
itemInputStreamList.add(new FileInputStream(new File(outFilePath)));
//这里添加你想替换的图片
// itemInputStreamList.add(new FileInputStream(new File(${图片路径})));

replaceItemList(zipInputStream, zipOutputStream, itemNameList, itemInputStreamList);
new File(outFilePath).delete();
logger.info("Word-docx文档生成完成");
}

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;
}

public static void replaceItemList(ZipInputStream zipInputStream, ZipOutputStream zipOutputStream, List<String> itemNameList, List<InputStream> itemInputStreamList){
if(null == zipInputStream){return;}
if(null == zipOutputStream){return;}
ZipEntry entryIn;
try {
while((entryIn = zipInputStream.getNextEntry())!=null){
String entryName = entryIn.getName();
ZipEntry entryOut = new ZipEntry(entryName);
zipOutputStream.putNextEntry(entryOut);
byte [] buf = new byte[8*1024];
int len;

if(itemNameList.indexOf(entryName) != -1){
// 使用替换流
while((len = (itemInputStreamList.get(itemNameList.indexOf(entryName)).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();
for (InputStream itemInputStream:itemInputStreamList) {
close(itemInputStream);
}
close(zipInputStream);
close(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
2
3
4
5
6
7
8
9
10
11
12
public class CX330 {

public static void main(String[] args) throws Exception {
Map<String, Object> data = new HashMap<>();
data.put("one", "RupertTears");
data.put("two", "Thought is already is late, exactly is the earliest time.");
data.put("three", "成功");
data.put("six", "成功6");
data.put("five", "成功5");
GenerateDocxUtil.freemarkerDocxTest("C:\\Users\\lenovo\\Desktop\\res\\res\\res\\res\\", data, "C:\\Users\\lenovo\\Desktop\\巡检报告xx622.docx");
}
}