主要是借助 poi-tl 来实现业务需求
当时第一次尝试的是Apache poi不是很好用,不推荐
第二次是xml,找的眼睛都花了,不推荐
要求:jdk1.8+,Apache POI5.2.2+ 我这里使用的是5.2.3版本
java
<!-- Apache POI -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.3</version>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.2</version>
</dependency>
注意这里需要确保没有其他的版本的poi,否则项目启动会报找不到类等错误,例如出现 java.lang.NoSuchFieldError:Factory
解决方式:此问题是由pom依赖导致,通过Ctrl+N查看ThemeDocument类,出现多个版本,发现引入了两个不同版本的poi包,导致版本冲突。
其中NoSuchMethodError 、ClassNotFoundException 、NoClassDefFoundError异常都是版本不对的问题,需要升级版本
代码部分
java
// 利用map结构存储数据
Map<String, Object> data = new HashMap<>();
// 指定路径 compile 编译模板 render添加数据源
XWPFTemplate template = XWPFTemplate.compile("xxx.docx").render(data);
try {
//write 输出到流
template.writeAndClose(new FileOutputStream(输出路径"));
} catch (IOException e) {
e.printStackTrace();
log.error("写入文件出错了");
}
模板部分,使用poi-tl最大的难点或者说工作量在于模板的制作,具体可以看上面文档,文档中拥有具体格式。
- 普通替换,只需要{{属性名}}
- 逻辑判断是否显示:{{?属性名}}...{{/属性名}}
- 列表{{*列表名}} 在这里,我单纯只使用了List<String>,文档中有更复杂的形式,包括对象
- 表格我这里没有涉及到,不做考虑