使用POI直接编辑word是有难度的,word有段落paragraph和run,另外表格和图片也是独立的,并不像html标签那样有明确的界限。所以编辑word最好就是使用模板的方式。
poi-tl(poi template language)是Word模板引擎,基于Microsoft Word模板和数据生成新的文档。poi-tl是一个免费开源的Java类库,你可以非常方便的加入到你的Java项目中。
poi-tl官网:http://deepoove.com/poi-tl/
poi-tl入门教程:http://deepoove.com/poi-tl/apache-poi-guide.html
1. Why poi-tl
方案 | 移植性 | 功能性 | 易用性 |
---|---|---|---|
Poi-tl |
Java跨平台 |
Word模板引擎 |
基于Apache POI |
Apache POI |
Java跨平台 |
Apache项目,功能丰富 |
文档不全,这里有一个教程:http://deepoove.com/poi-tl/apache-poi-guide.html |
Freemarker |
XML跨平台 |
仅支持文本,很大的局限性 |
复杂,需要维护XML结构,代码不可维护 |
OpenOffice |
部署OpenOffice软件,移植性较差 |
- |
复杂,需要了解OpenOffice的API |
HTML浏览器导出 |
依赖浏览器的实现,移植性较差 |
HTML不能很好的兼容Word的格式 |
- |
Jacob、winlib |
Windows平台 |
- |
复杂,完全不推荐使用 |
Apache POI不仅在上层封装了易用的文档API(文本、图片、表格、页眉、页脚、图表等),也可以在底层直接操作文档XML结构,poi-tl正是一个基于Apache POI的Word模板引擎,并且拥有着让人喜悦的特性。
引擎功能 | 描述 |
---|---|
文本 |
将标签渲染为文本 |
图片 |
将标签渲染为图片 |
表格 |
将标签渲染为表格 |
列表 |
将标签渲染为列表 |
图表 |
条形图(3D条形图)、柱形图(3D柱形图)、面积图(3D面积图)、折线图(3D折线图)、雷达图、饼图(3D饼图)等图表数据渲染 |
If Condition判断 |
隐藏或者显示某些文档内容(包括文本、段落、图片、表格、列表等) |
Foreach Loop循环 |
循环某些文档内容(包括文本、段落、图片、表格、列表等) |
Loop表格行 |
循环渲染表格的某一行 |
Loop有序列表 |
支持有序列表的循环,同时支持多级列表 |
图片替换 |
将原有图片替换成另一张图片 |
书签、锚点、超链接 |
支持设置书签,文档内锚点和超链接功能 |
强大的表达式 |
完全支持SpringEL表达式,可以扩展更多的表达式:OGNL, MVEL… |
标签定制 |
支持自定义标签前后缀 |
文本框 |
文本框内标签支持 |
样式 |
模板即样式,同时代码也可以设置样式 |
模板嵌套 |
模板包含子模板,子模板再包含子模板 |
Merge合并 |
Word合并,可以在指定位置进行合并 |
用户自定义函数(插件) |
在文档任何位置执行函数 |
poi-tl是一个免费开源的Java类库,你可以非常方便的加入到你的Java项目中。
2. 软件要求
-
Apache POI 4.1.2+
-
JDK 1.8+
3. 历史版本
点击下方链接查阅poi-tl历史版本文档,其中v1.5.x是构建在Apache poi3.16+和JDK1.6+上的版本:
-
1.7.x Documentation
-
1.6.x Documentation
-
1.5.x Documentation
4. Getting Started
4.1. Maven
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.8.2</version>
</dependency>
4.2. Gradle
compile group: 'com.deepoove', name: 'poi-tl', version: '1.8.2'
4.3. 2min快速入门
新建Word模板template.docx,包含标签 {{title}}
template.docx内容如下
{{title}}
代码示例
XWPFTemplate template = XWPFTemplate.compile("template.docx").render(
new HashMap<String, Object>(){{
put("title", "Hi, poi-tl Word模板引擎");
}});
FileOutputStream out = new FileOutputStream("output.docx");
template.write(out);
out.flush();
out.close();
template.close();
TDO模式:Template + data-model = output
output.docx内容如下
Hi, poi-tl Word模板引擎
4.4. Template:模板
模板就要所见即所得。
模板是Docx格式的Word文档,你可以使用Microsoft office、WPS Office、Pages等任何你喜欢的软件制作模板。
所有的标签都是以 {{
开头,以 }}
结尾,模板标签可以出现在任何位置,包括页眉,页脚,表格内部,文本框等等。poi-tl遵循“所见即所得”的设计,模板的样式会被完全保留,标签的样式也会应用在替换后的文本上。
表格布局可以设计出很多优秀专业的文档,模板推荐使用表格布局。
4.5. Data-model:数据
数据模型类似于哈希、字典。
数据可以是Map(key是标签名称):
Map<String, Object> data = new HashMap<>();
data.put("name", "Sayi");
data.put("start_time", "2019-08-04");
数据可以是对象(属性名是标签名称):
public class Data {
private String name;
private String startTime;
// {{author.XXX}}
private Author author;
}
数据可以是树结构,每级之间用点来分隔开,比如
{{author.name}}
标签对应的数据是author对象的name属性值。
FreeMarker、Velocity文本模板中可以通过三个标签设置图片路径、宽和高:
<img class="lazy" data-original="{{path}}" width="{{width}}" height="{{height}}">
但是Word模板不是由简单的文本表示,所以在渲染图片、表格等元素时提供了数据模型,它们都实现了接口 RenderData
,比如图片数据模型 PictureRenderData
包含图片路径、宽、高三个属性。
4.6. Output:输出
以流的方式进行输出:
// 输出流
template.write(OutputStream stream)
可以写到任意输出流中,比如文件流FileOutputStream或网络流ServletOutputStream:
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition","attachment;filename=\""+"out_template.docx"+"\"");
// HttpServletResponse response
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
template.close();
bos.flush();
bos.close();
out.flush();
out.close();
最后不要忘记关闭这些流。