word导出 poi-tl 动态表格、合并单元格

word导出 poi-tl 动态表格、合并单元格

    • 一、动态表格
      • 1、使用TableRenderData
      • 2、使用List方式
    • 二、列表
      • 1、NumberingRenderData
      • 2、List
    • 三、区块对 {{?sections}}{{/sections}}
    • 四、SpringEL表达式使用
    • 五、表格单元格合并
    • 六、官方示例

1、动态表格 {{#var}}
2、列表 {{*var}}
3、区块对 {{?sections}} {{/sections}}
4、SpringEL表达式使用
5、表格单元格合并
注意:表格外使用{{test}},表格内使用[test] 设置变量

一、动态表格

1、使用TableRenderData

eg1: 基础表格

// 一个2行2列的表格
put("table0", Tables.of(new String[][] {
                new String[] { "00", "01" },
                new String[] { "10", "11" }
            }).border(BorderStyle.DEFAULT).create());

在这里插入图片描述

eg2:表格样式示例

// 表头居中且背景为蓝色
RowRenderData row0 = Rows.of("姓名", "学历").textColor("FFFFFF")
      .bgColor("4472C4").center().create();
RowRenderData row1 = Rows.create("李四", "博士");
put("table1", Tables.create(row0, row1));

在这里插入图片描述

2、使用List方式

![word中表格,表头固定](https://img-blog.csdnimg.cn/c6242c1a70e24faf9db63101a1430dc1.png)
上图为word中表格,表头固定
List<Map<String, Object>> table1 = new ArrayList<>();
for(int i = 0; i < 5; i++) {
		Map<String, Object> zkMap = new HashMap<>();
        zkMap.put("name", "张三" + i);
        zkMap.put("age", 25);
        zkMap.put("job", "xxx");
        zkMap.put("conten", "xxx");
        zkMap.put("year", "2023");
        table1.add(zkMap);
}

二、列表

1、NumberingRenderData

eg1:默认

map.put("list", Numberings.create("Plug-in grammar",
                    "Supports word text, pictures, table...",
                    "Not just templates"));

eg2:设置编号样式Numberings.of(NumberingFormat)

// DECIMAL //1. 2. 3.
// DECIMAL_PARENTHESES //1) 2) 3)
// BULLET //● ● ●
// LOWER_LETTER //a. b. c.
// LOWER_ROMAN //i ⅱ ⅲ
// UPPER_LETTER //A. B. C.
map.put("list", Numberings.of(NumberingFormat.DECIMAL)
	.addItem("Plug-in grammar")
	.addItem("Supports word text").create());

2、List

三、区块对 {{?sections}}{{/sections}}

标签内的内容:false或空集合时不显示标签元素
循环中的内置变量:
word导出 poi-tl 动态表格、合并单元格_第1张图片

eg1:简单示例
{{?ex}}
{{titile}}
{{/ex}}


eg2:表格循环

word 示例:
word导出 poi-tl 动态表格、合并单元格_第2张图片
最外层的类:

@Data
public class TReportInformDataVO {

    @ApiModelProperty(value = "报告日期")
    private String generateDate;
    
    @ApiModelProperty(value = "gk数据")
    private List<InformGKDataVO> GKDESC;
    
}

循环表格的类:

@Data
    public static class InformGKDataVO {

        @ApiModelProperty(value = "表格index")
        private Integer index;

        @ApiModelProperty(value = "企业名称")
        private String entName;

        private String reportYear;

        private String reportMonth;

        @ApiModelProperty(value = "gk数据表格")
        private List<InformGKTableDataVO> gkTable;

        @Data
        public static class InformGKTableDataVO {

            @ApiModelProperty(value = "名称")
            private String name;

            @ApiModelProperty(value = "数据项")
            private String item;

            @ApiModelProperty(value = "单位")
            private String unit;

            @ApiModelProperty(value = "填报值")
            private String reportData;

            @ApiModelProperty(value = "gk数据")
            private String gkData;

            @ApiModelProperty(value = "偏差")
            private String offset;

        }
    }

结果如下:
word导出 poi-tl 动态表格、合并单元格_第3张图片
word导出 poi-tl 动态表格、合并单元格_第4张图片

四、SpringEL表达式使用

注意:
1、使用SpringEL表达式需要将标签配置为SpringEL模式
2、表达式在idea 或 其他文本工具 写好后再复制到word文档中

// java
builder.useSpringEL();

SpringEL表达式:

# 日期格式化
{{new java.text.SimpleDateFormat('yyyy-MM-dd HH:mm:ss').format(time)}} 
# 三目运算
{{sex ? '男' : '女'}} 
# 设置文本样式:可以使用el表达式,也可以在java代码里设置
[status=='0'?'通过':new com.deepoove.poi.data.TextRenderData('FF0000','不通过')]

五、表格单元格合并

合并单元格的Policy,继承DynamicTableRenderPolicy

@Accessors(chain = true)
public class MergeRowModelRenderPolicy extends DynamicTableRenderPolicy {
    // 需要合并的列,从0开始
    List<Integer> mergeColumns = Arrays.asList(0);
    // 表格所有的列数
    Integer colNum = 5;

    @Override
    public void render(XWPFTable table, Object data) throws Exception {
        if (data == null) {
            return;
        }
        if (CollUtil.isEmpty(mergeColumns)) {
            return;
        }
        if (colNum == null) {
            return;
        }
        
        // 需要处理的数据
        List<TReportInformDataVO.InformGKDataVO.InformGKTableDataVO> dataList = (List<TReportInformDataVO.InformGKDataVO.InformGKTableDataVO>) data;

		// 表格所有行
        List<RowRenderData> detailData = new ArrayList<>();
        if (data != null) {
            table.removeRow(1);
            for (int i = dataList.size() - 1; i >= 0; i--) {
                //根据数据长度创建对应行数
                XWPFTableRow insertNewTableRow = table.insertNewTableRow(1);
                for (int j = 0; j < colNum; j++) {
                    //根据列的数量创建对应单元格
                    insertNewTableRow.createCell();
                }
                // 单行渲染
                TReportInformDataVO.InformGKDataVO.InformGKTableDataVO item = dataList.get(i);
                // rowBuilder.center().verticalCenter() 表格内容居中
                // rowBuilder.rowAtleastHeight(1) 设置表格高度
                RowRenderData rowRenderData = Rows.of(item.getGeneratorSystemName(), item.getItem() + "(" + item.getUnit() + ")", item.getReportData(), item.getGkData(), item.getOffset()).center().verticalCenter().rowAtleastHeight(1).create();
                detailData.add(rowRenderData);
                // 填充表格
                TableRenderPolicy.Helper.renderRow(table.getRow(1), rowRenderData);
            }

            List<Map<Integer, MergeRowVo>> lstCol = new ArrayList<>();
            // 循环列
            mergeColumns.forEach(x -> {
                Map<Integer, MergeRowVo> mapsCol = new HashMap<>();
                for (int i = 0; i < detailData.size(); i++) {
                	// 要和下一行的内容比较,避免数组越界
                    if (i + 1 > detailData.size() - 1) {
                        break;
                    }
                  
                    List<CellRenderData> cells = detailData.get(i).getCells();
                    List<CellRenderData> nextCells = detailData.get(i + 1).getCells();
					// ***默认单元格合并要参考第0列
                    if (cells.get(0).getParagraphs().get(0).getContents().get(0).toString().equals(nextCells.get(0).getParagraphs().get(0).getContents().get(0).toString())) {
                    // 判断第x列 == 第x+1列 ?
                        if (cells.get(x).getParagraphs().get(0).getContents().get(0).toString().equals(nextCells.get(x).getParagraphs().get(0).getContents().get(0).toString())) {
                            if (mapsCol.containsKey(x)) {
                                mapsCol.put(x, new MergeRowVo().setStartRow(mapsCol.get(x).getStartRow()).setEndRow(i + 2));
                            } else {
                                mapsCol.put(x, new MergeRowVo().setStartRow(i + 1).setEndRow(i + 2));
                            }
                        }
                    } else {
                        lstCol.add(new HashMap<>(mapsCol));
                        mapsCol.clear();
                    }
                }
                if (mapsCol.size() > 0) {
                    lstCol.add(new HashMap<>(mapsCol));
                    mapsCol.clear();
                }
            });
            lstCol.forEach(mapsCol -> {
                mapsCol.keySet().forEach(key -> {
                // 单元格合并
                    TableTools.mergeCellsVertically(table, key, mapsCol.get(key).getStartRow(), mapsCol.get(key).getEndRow());
                });
            });
        }
    }
}

六、官方示例

地址:
poi-tl官方示例:http://deepoove.com/poi-tl/#_%E7%A4%BA%E4%BE%8B_5

你可能感兴趣的:(word,java)