OpenSource - Apache POI 的 Word 模板引擎 poi-tl

发布于:2025-03-11 ⋅ 阅读:(16) ⋅ 点赞:(0)

在这里插入图片描述


概述

该项目是基于 Apache POI 的 Word 模板引擎,可以动态生成 Word 文档。它提供了友好的 API,支持文本、图片、表格、条件渲染、图表等多种内容的渲染,适用于批量生成合同、报告、通知、证书等场景

在这里插入图片描述


地址

https://github.com/Sayi/poi-tl

https://deepoove.com/poi-tl/


Word模板引擎功能

功能 描述
文本 将标签渲染为文本
图片 将标签渲染为图片
表格 将标签渲染为表格
列表 将标签渲染为列表
图表 支持条形图(3D条形图)、柱形图(3D柱形图)、面积图(3D面积图)、折线图(3D折线图)、雷达图、饼图(3D饼图)、散点图等图表渲染
If Condition判断 根据条件隐藏或者显示某些文档内容(包括文本、段落、图片、表格、列表、图表等)
Foreach Loop循环 根据集合循环某些文档内容(包括文本、段落、图片、表格、列表、图表等)
Loop表格行 循环复制渲染表格的某一行
Loop表格列 循环复制渲染表格的某一列
Loop有序列表 支持有序列表的循环,同时支持多级列表
Highlight代码高亮 Word中代码块高亮展示,支持26种语言和上百种着色样式
Markdown 将Markdown渲染为Word文档
Word批注 完整的批注功能,创建批注、修改批注等
Word附件 Word中插入附件
SDT内容控件 内容控件内标签支持
Textbox文本框 文本框内标签支持
图片替换 将原有图片替换成另一张图片
书签、锚点、超链接 支持设置书签,文档内锚点和超链接功能
Expression Language 完全支持SpringEL表达式,可以扩展更多的表达式:OGNL, MVEL…​
样式 模板即样式,同时代码也可以设置样式
模板嵌套 模板包含子模板,子模板再包含子模板
合并 Word合并Merge,也可以在指定位置进行合并
用户自定义函数(插件) 插件化设计,在文档任何位置执行函数

Getting Started

前提

JDK1.8+
Apache POI5.2.2+

Maven

<dependency>
  <groupId>com.deepoove</groupId>
  <artifactId>poi-tl</artifactId>
  <version>1.12.2</version>
</dependency>

Gradle

implementation 'com.deepoove:poi-tl:1.12.2'

2分钟入门

新建Word文档template.docx,包含标签 {{title}}

template.docx
{{title}}

代码示例

XWPFTemplate template = XWPFTemplate.compile("template.docx").render(
  new HashMap<String, Object>(){{
    put("title", "Hi, poi-tl Word模板引擎");
}});   // 
template.writeAndClose(new FileOutputStream("output.docx")); 
  • compile 编译模板
  • render 渲染数据
  • write 输出到流
  • TDO模式:Template + data-model = output
output.docx
Hi, poi-tl Word模板引擎

Template:模板

模板是Docx格式的Word文档,你可以使用Microsoft office、WPS Office、Pages等任何你喜欢的软件制作模板,也可以使用Apache POI代码来生成模板。

所有的标签都是以{{开头,以}}结尾,标签可以出现在任何位置,包括页眉,页脚,表格内部,文本框等,表格布局可以设计出很多优秀专业的文档,推荐使用表格布局。

poi-tl模板遵循“所见即所得”的设计,模板和标签的样式会被完全保留。

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;
  private Author author;
}

数据可以是树结构,每级之间用点来分隔开,比如{{author.name}}标签对应的数据是author对象的name属性值。

FreeMarker、Velocity文本模板中可以通过三个标签设置图片路径、宽和高:<img src="{{path}}" width="{{width}}" height="{{height}}">, 但是Word模板不是由简单的文本表示,所以在渲染图片、表格等元素时提供了数据模型,它们都实现了接口 RenderData ,比如图片数据模型 PictureRenderData 包含图片路径、宽、高三个属性。


Output:输出

以流的方式进行输出:

template.write(OutputStream stream);

比如文件流:

template.write(new FileOutputStream("output.docx"));

比如网络流:

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);
bos.flush();
out.flush();

最后不要忘记关闭这些流。

PoitlIOUtils.closeQuietlyMulti(template, bos, out);

在这里插入图片描述