前言

前段时间在使用poi-tl的时候,发现官网无法访问,查阅资料不太方便,只能研究poi-tl源码,来解决问题,虽然想在项目上已经舍弃了poi-tl,但是并不代表它不好用,所以这里做一下分享和总结

当然并不只有poi一种方式,还有:Apache POI、Freemarker、OpenOffice、PageOffice、OnlyOffice

认识poi-tl

poi-tl是一个基于Word模板和数据生成新文档的Word模板引擎。

Word模板样式丰富。Poi-tl将在生成的文档中完美地保留模板中的样式。您还可以设置标签的样式。标签的样式将应用于替换的文本,因此您可以专注于模板设计。

​poi-tl是一个”无逻辑”的模板引擎。没有复杂的控制结构和变量赋值,只有标签,有些标签可以用文字、图片、表格等代替。一些标签会隐藏某些文档内容,而另一些标签会循环一系列文档内容。

​poi-tl支持自定义函数(插件),函数可以在Word模板的任何地方执行,在文档的任何地方做任何事情是poi-tl的目标。

整合(Maven)

1
2
3
4
5
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.10.0</version>
</dependency>

使用

  • 最简单的示例:绑定标签{{name}}、{{age}}、{{gender}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void main(String[] args) throws Exception {
Map<String, Object> mxMap = new HashMap();
mxMap.put("name", "满心");
mxMap.put("age", "18");
mxMap.put("gender", "男");
//文件缓存目录
File mxFile = new File("E:\\wordTmp");
XWPFTemplate template = XWPFTemplate.compile("E:\\mxTemplate.docx").render(mxMap);
//缓存到本地
template.writeAndClose(new FileOutputStream(mxFile));
if (!mxFile.exists()) {
mxFile.mkdirs();
}
}
  • 对应word中标签写法

渲染后的样式,可直接在mxTemplate中调整即可,例如:加粗、居中、颜色等等,和word操作一样

姓名年龄性别
{{name}}{{age}}{{gender}}

从上可以看出,poi的语法就是双花括号{{}},下面具体看看有哪些标签:

Tags标签

文本标签

文本标签{{val}}

相关属性:

  1. String:文本
  2. TextRenderData:样式
  3. HyperlinkTextRenderData:超链接和锚点
  4. Object:用toString()方法转化为文本

普通示例

1
2
3
Map<String, Object> mxMap = new HashMap();
mxMap.put("name", new TextRenderData("000000", "满心"));
mxMap.put("age", new HyperlinkTextRenderData("url", "https://blog.lovelu.top"));

链式代码示例

1
2
mxMap.put("name", Texts.of("满心").color("000000").create());
mxMap.put("age", Texts.of("url").link("https://blog.lovelu.top").create())

标签的样式将应用于替换后的文本,文本的样式也可以通过代码设置,总体上来说,还是很便利的

TextRenderData结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"text": "满心",
"style": {
"strike": false,
"bold": true,
"italic": false,
"color": "000000",
"underLine": false,
"fontFamily": "微软雅黑",
"fontSize": 12,
"highlightColor": "green",
"vertAlign": "superscript",
"characterSpacing" : 20
}
}

图片标签

图片标签{{@val}}

相关属性:(以下属性不在逐一解释,字面意思即可理解)

  1. String:图片url或本地路径,默认为图片原始尺寸
  2. PictureRenderData
  3. ByteArrayPictureRenderData
  4. FilePictureRenderData
  5. UrlPictureRenderData

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 指定图片url
mxMap.put("img", "https://blog.lovelu.top/logo.webp");

// 设置宽高
mxMap.put("img", Pictures.ofLocal("logo.webp").size(240, 240).create());

// 图片流
mxMap.put("streamImg", Pictures.ofStream(new FileInputStream("logo.jpeg"), PictureType.WPG)
.size(100, 120).create());

// 网络图片
mxMap.put("urlImg", Pictures.ofUrl("http://deepoove.com/images/icecream.png")
.size(100, 100).create());

// java图片
mxMap.put("buffered", Pictures.ofBufferedImage(bufferImage, PictureType.PNG)
.size(100, 100).create());

FilePictureRenderData结构

1
2
3
4
5
6
7
8
9
{
"pictureType" : "WPG",
"path": "logo.webp",
"pictureStyle": {
"width": 100,
"height": 100
},
"altMeta": "图片不存在"
}

表格标签

表格标签{{#val}}

相关属性:

  1. TableRenderData

建议使用Table、Cells、Rows来构建表格

基础示例

1
2
3
4
5
// 2行2列
mxMap.put("table0", Tables.of(new String[][] {
new String[] { "00", "01" },
new String[] { "10", "11" }
}).border(BorderStyle.DEFAULT).create());

样式示例

1
2
3
4
5
// 表示:给第0行设置背景色,以及居中
RowRenderData row0 = Rows.of("姓名", "年龄").textColor("FFFFFF")
.bgColor("000000").center().create();
RowRenderData row1 = Rows.create("满心", "18");
mxMap.put("mxtable", Tables.create(row0, row1));

效果如下

姓名年龄性别
满心18

表格样式示例

1
2
3
4
5
// 合并第一行单元格
RowRenderData row0 = Rows.of("cell0", "cell1", "cell2").center().bgColor("ffffff").create();
RowRenderData row1 = Rows.create("暂无数据", null, null);
MergeCellRule rule = MergeCellRule.builder().map(Grid.of(1, 0), Grid.of(1, 2)).build();
put("table3", Tables.of(row0, row1).mergeRule(rule).create());

效果如下:

cell0cell1cell2
暂无数据

TableRenderData表格模型的单元格中可展示文本、图片,也可单独设置样式

TableRenderData结构

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
{
"rows": [
{
"cells": [
{
"paragraphs": [
{
"contents": [
{
[TextRenderData]
},
{
[PictureRenderData]
}
],
"paragraphStyle": null
}
],
"cellStyle": {
"backgroundColor": "00000",
"vertAlign": "CENTER"
}
}
],
"rowStyle": {
"height": 2.0f
}
}
],
"tableStyle": {
"width": 14.63f,
"colWidths": null
},
"mergeRule": {
"mapping": {
"0-0": "1-2"
}
}
}

列表标签

列表标签{{*val}}

相关属性:

  1. List<String>
  2. NumberingRenderData

普通示例

1
mxMap.put("list", Numberings.create("满心记","share technology","share life"));

同时支持罗马字符、有序无序,通过Numberings.of(NumberingFormat)来使用

1
2
3
4
5
6
DECIMAL // 1. 2. 3.
DECIMAL_PARENTHESES // 1) 2) 3)
BULLET // ● ● ●
LOWER_LETTER // a. b. c.
LOWER_ROMAN // i ⅱ ⅲ
UPPER_LETTER // A. B. C.

多系列图表

多系列图表指的是条形图(3D条形图)、柱形图(3D柱形图)、面积图(3D面积图)、折线图(3D折线图)、雷达图、散点图等。

多系列图表的标签是一个文本:,标签位置在:图表区格式—可选文字—标题(新版本Microsoft Office标签位置在:编辑替换文字-替换文字)

相关属性:

  1. ChartMultiSeriesRenderData

普通示例

1
2
3
4
5
6
7
ChartMultiSeriesRenderData chart = Charts
.ofMultiSeries("ChartTitle", new String[] { "中文", "English" })
.addSeries("countries", new Double[] { 30.0, 12.0 })
.addSeries("speakers", new Double[] { 200.0, 110.0 })
.create();
mxMap.put("totalChar", chart);

ChartMultiSeriesRenderData结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
"chartTitle": "ChartTitle",
"categories": [
"中文", "English"
],
"seriesDatas": [
{
"name": "countries",
"values": [
15, 6
]
},
{
"name": "speakers",
"values": [
223, 119
]
}
]
}

当然poi肯定不止这么多标签,我所使用到的就是上面这些,想了解更多标签可参考下面这篇文章

参考知春秋