5. 插件机制(Plugin mechanism)
插件机制是poi-tl的核心,默认的五大內建模板语法是通过插件方式加载的。插件的核心逻辑是在模板的基础上通过poi-tl和poi提供的API操作word文档,实现插件就是实现自己的渲染策略。
由于需要操作Word文档,我们需要掌握一些Apache POI API的知识,可以参见Apache官方API,这里也有一个快速入门的教程:Apache POI Word(docx) 入门示例教程。如果你写了一个不错的插件,欢迎提交Pull Request。 |
5.1. 新增RenderPolicy策略
內建策略是poi-tl自带的一些渲染策略,用来处理文本、图片、列表、表格、文档合并等:
TextRenderPolicy
PictureRenderPolicy
NumbericRenderPolicy
MiniTableRenderPolicy
DocxRenderPolicy
我们可以通过实现 RenderPolicy
接口扩展自己的渲染策略:
public interface RenderPolicy {
void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template); (1) (2) (3)
}
1 | ElementTemplate是当前模板标签所在位置 |
2 | data是数据模型 |
3 | 通过XWPFTemplate获得Apache POI增强类NiceXWPFDocument,继而可以在当前模板标签位置插入段落,图片,表格等 |
原则上Apache POI支持的操作,都可以在当前模板位置进行渲染。 |
示例:我们创建一个自己的表格渲染策略CustomTableRenderPolicy,使用表格API来操作表格,doc.insertNewTable()
是在当前模板位置插入表格,正如可以实现任何渲染逻辑一样,我们可以随心所欲的操作表格了。
AbstractRenderPolicy是一个抽象模板类,定义了一些骨架步骤并且将数据模型的校验和渲染逻辑分开,新的策略继承AbstractRenderPolicy类不是必须的。
public class CustomTableRenderPolicy extends AbstractRenderPolicy<Object> {
@Override
protected void afterRender(RenderContext context) {
// 清空模板标签所在段落
clearPlaceholder(context, true);
}
@Override
public void doRender(RunTemplate runTemplate, Object data, XWPFTemplate template)
throws Exception {
NiceXWPFDocument doc = template.getXWPFDocument();
XWPFRun run = runTemplate.getRun();
// 定义行列
int row = 10, col = 8;
// 插入表格
XWPFTable table = doc.insertNewTable(run, row, col);
// 定义表格宽度、边框和样式
TableTools.widthTable(table, MiniTableRenderData.WIDTH_A4_FULL, col);
TableTools.borderTable(table, 4);
// 调用XWPFTable API操作表格:data对象可以包含任意你想要的数据,包括图片文本等
// 调用MiniTableRenderPolicy.Helper.renderRow方法快速方便的渲染一行数据
// 调用TableTools类方法操作表格,比如合并单元格
// ......
TableTools.mergeCellsHorizonal(table, 0, 0, 7);
TableTools.mergeCellsVertically(table, 0, 1, 9);
}
}
5.2. 自定义模板策略
所有的插件都是通过如下构建器来配置:
ConfigureBuilder builder = Configure.newBuilder();
XWPFTemplate.compile("~/template.docx", builder.buid());
当我们有个模板标签为{{report}},它本身是一个文本模板,如果希望在这个位置做些不一样或者更复杂的事情,我们可以通过构建器设定模板的渲染策略:
builder.customPolicy("report", new MyRenderPolicy());
5.3. 新增语法插件
比如增加%语法:{{%var}},对应自定义的渲染策略 PercentRenderPolicy
,加载插件代码如下:
builder.addPlugin('%', new PercentRenderPolicy());
由于內建模板也是通过插件方式加载的,我们甚至可以改变它们的语法:
builder.addPlugin('@', new MiniTableRenderPolicy());
builder.addPlugin('#', new PictureRenderPolicy());
这样{{@var}}就变成了表格模板,{{#var}}变成了图片模板,虽然不建议改变內建模板,但是从中可以看到poi-tl插件的设计思想,深藏功与名。
5.4. Helper辅助类
在內建策略中,通常会提供一个静态Helper辅助类,在我们实现自己的RenderPolicy时,也可以通过这些辅助类操作文档。
// 某个位置渲染文本
TextRenderPolicy.Helper.renderTextRun(XWPFRun, Object);
// 某个位置渲染图片
PictureRenderPolicy.Helper.renderPicture(XWPFRun, PictureRenderData);
// 某个位置渲染列表
NumbericRenderPolicy.Helper.renderNumberic(XWPFRun, NumbericRenderData);
// 渲染表格的一行数据
MiniTableRenderPolicy.Helper.renderRow(XWPFTable, int, RowRenderData);
// 渲染单元格
MiniTableRenderPolicy.Helper.renderCell(XWPFTableCell, CellRenderData, TableStyle)