转载,原文地址:
https://github.com/Sayi/sayi.github.com/issues/21
表格对于页面的布局具有重大的意义,正因为其灵活性,所以用模板引擎处理word中的Table时,显得并不是那么简单,本文将讨论如何利用poi-tl(1.2.0版本)提供的工具来简化表格处理。关于如何使用poi-tl,参见中文Wiki
poi-tl默认实现了N行N列的样式(如下图),同时提供了当数据为空时,展示一行空数据的文案(如下图中的No Data Descs)。
在poi-tl的1.2.0版本中,表格模板语法是#,数据结构是com.deepoove.poi.data.TableRenderData。
1. 表格头使用headers[]定义,支持设置背景色
2. 表格数据使用datas[]定义,不同列的数据在datas中使用分号隔开
3. 宽度使用width定义
4. 无数据文案使用noDatadesc定义
{
"datas": [
"beijing;beijing",
"zhejiang;hangzhou"
],
"headers": [
{
"style": {
"color": "1E915D",
"fontSize": 0
},
"text": "province"
},
{
"style": {
"color": "1E915D",
"fontSize": 0
},
"text": "city"
}
],
"noDatadesc": "no datas",
"width": 0
}
具体Java代码参考:
@Test
public void testTable() throws Exception {
Map datas = new HashMap() {
{
// 有表格头 有数据
put("table", new TableRenderData(new ArrayList() {
{
add(new TextRenderData("1E915D", "province"));
add(new TextRenderData("1E915D", "city"));
}
}, new ArrayList
是一个点的二十分之一,或者是1440分之一英寸。官方解释如下:
dxa - Specifies that the value is in twentieths of a point (1/1440 of an inch).
首先1英寸=2.54厘米,A4纸大小为21cm*29.7cm。
如果这个width设置成5670,则表示这个表格的宽度是10cm。
抛开对这个单位理解的难度,我们最常见的应该是宽度自适应和宽度最大。
如果在poi-tl中设置了width=0,则表格是宽度自适应的。
以A4纸为例,页面宽度为21cm,左右页边距各位3.17cm,则表格的width=(21-3.17*2)/2.54*1440,大约为8310。
但是,很多业务场景并不仅限于如此简单的表格布局,产品需求总是丰富多彩的。poi-tl对XWPFDocument进行了封装,增强实现了一些基本功能。在com.deepoove.poi.NiceXWPFDocument
中提供了合并的功能。
/**
* 合并行单元格
* @param table
* @param row
* @param fromCol
* @param toCol
*/
public void mergeCellsHorizonal(XWPFTable table, int row, int fromCol,
int toCol)
/**
* 合并列单元格
* @param table
* @param col
* @param fromRow
* @param toRow
*/
public void mergeCellsVertically(XWPFTable table, int col, int fromRow,
int toRow)
我们完全可以从无到有去创建一个新的表格。
XWPFTemplate template = XWPFTemplate.compile("src/test/resources/complex.docx");
template.registerPolicy("table", new MyTableRenderPolicy());
RenderPolicy
接口@Override
public void render(ElementTemplate eleTemplate, Object data, XWPFTemplate template) {
NiceXWPFDocument doc = template.getXWPFDocument();
RunTemplate runTemplate = (RunTemplate) eleTemplate;
XWPFRun run = runTemplate.getRun();
if (null == data) return;
//doc.insertNewTable(run, row, col);
//doc.mergeCellsHorizonal(table, 1, 0, 1);
//...
runTemplate.getRun().setText("", 0);
}
至此,我们持有了NiceXWPFDocument和XWPFRun对象,可以插入表格,合并单元格等操作。
对于事先已知道部分表格样式,我们只需要处理剩余部分的表格可以采用此方式。
比如下图,我们在模板中设计好表格头和表格未的样式,表格中间的数据则可以动态处理。
DynamicTableRenderPolicy
。public class MyTableRenderPolicy extends DynamicTableRenderPolicy {
@Override
public void render(XWPFTable table, Object data) {
//table.getRow(1).getCell(0)
//XWPFTableRow row = table.insertNewTableRow(1);
//table.removeRow(1);
}
}
至此,我们可以通过XWPFTable对象对表格进行删除行列、增加行列、设置文字等操作。