需求:填充word模板,然后合并成一个word。
但是文件并不想保存在本地磁盘,直接再内存中处理完成,直接导出或者响应给前端下载;
pom如下:
<!--poi-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.2</version>
</dependency>
<!--word文档处理-->
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.2</version>
</dependency>
注意事项:
pom中会对docx文件压缩(如果你得模板是在resources下得话),所以得事先设置,否则会报错
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<version>2.6</version>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>docx</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
示例代码:
@Test
public void tex21() throws Exception {
List<ByteArrayInputStream> inputStreamList = new ArrayList<>();
for (int i = 0; i < 3; i++) {
// 读取模板文件 路径是你的模板位置
InputStream resourceAsStream = this.getClass().getResourceAsStream("/template/问题审查报告.docx");
//数据渲染
XWPFTemplate template = XWPFTemplate.compile(resourceAsStream).render(
new HashMap<String, Object>() {{
put("A1", "Hi, poi-tl Word模板引擎" + System.currentTimeMillis());
put("A2", "Hi, poi-tl " + System.currentTimeMillis());
put("A3", "Hi, poi-tl Word" + System.currentTimeMillis());
put("A4", " Word模板引擎" + System.currentTimeMillis());
put("E1", "D:\\google\\L\\1.png");
put("E2", Pictures.ofUrl("https://picx.zhimg.com/v2-679d833cf193239e0d5ea51a3d6bb7cb_r.jpg?source=1def8aca")
.size(100, 100).create()
);
}});
// 因为不想存到磁盘,再读取一边,所以直接在内存中处理完
// 输出到ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();//二进制OutputStream
template.writeAndClose(baos);//文档写入流
ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray());//new By
// 写入到磁盘
// FileOutputStream fileOutputStream = new FileOutputStream("D:\\word\\output" + System.currentTimeMillis() + ".docx");
// template.writeAndClose(fileOutputStream);
// 将所有填充好的模板收集成list
inputStreamList.add(in);
}
// 合并文档方法
tex22(inputStreamList);
}
// @Test
public void tex22(List<ByteArrayInputStream> inputStreamList) throws Exception {
//导出的位置
String mergedFileName = "D:\\word\\hb" + System.currentTimeMillis() + ".docx";
// List<File> inputFiles = new ArrayList<>();
// inputFiles.add(new File("D:\\word\\output1713836542115.docx"));
// inputFiles.add(new File("D:\\word\\output1713836639166.docx"));
// 生成新文档
FileOutputStream out = new FileOutputStream(mergedFileName);
// 合并文档 main主文档
NiceXWPFDocument main = new NiceXWPFDocument(Files.newInputStream(Paths.get("D:\\word\\2.docx")));
// 遍历所有模板
// 也可以使用 list<file> 获取inputStream也行 但是需要存本地盘,很麻烦还得删,也不是所有的服务器都有权限
for (ByteArrayInputStream byteArrayInputStream : inputStreamList) {
NiceXWPFDocument sub = new NiceXWPFDocument(byteArrayInputStream);
// 合并文档 sub子文档
main = main.merge(sub);
}
//写出到文件 或者响应成流传给前端下载,都行
main.write(out);
// 关闭流
main.close();
out.close();
}