poi-tl自定义渲染策略学习

文章介绍了如何在Java中通过自定义渲染策略实现Word表格的动态渲染,包括GksxRowData类的定义、表格数据处理、DynamicTableRenderPolicy的继承和使用,以及需要注意的模板匹配、数据绑定和单元格合并等要点。
摘要由CSDN通过智能技术生成

实现逻辑

自定义渲染策略实现逻辑:

  • 找到模板中的表格标签
  • render方法接收java中对应模板表格标签的所有list数据
  • 执行自定义渲染逻辑

参考代码

word模板如下:
在这里插入图片描述
实体类:

@Data
public class GksxRowData {
    /**
     * problemType 问题类型
     */
    private String problemTypeDesc;
    /**
     * 序号
     */
    private String num;

    /**
     * problemContent 问题描述
     */
    private String problemContent;

    /**
     * problemScore 扣除分值
     */
    private BigDecimal problemScore;

    /**
     * 1集团巡视审计专项检查的长度
     */
    private Integer typeOneSize;

    /**
     * 2集团研发专项检查的长度
     */
    private Integer typeTwoSize;
}

@Data
public class GksxTableData {
	/**
	 * 待渲染的数据 (扣分详细+合计)
	 */
	private List<GksxRowData> gksxRowDataList;

}

@Data
public class JxWordExport {
    /**
     * 管控事项table表格
     */
    private GksxTableData gksxTable;
}

自定义渲染策略类:

@Slf4j
public class TemplateGksxTablePolicy extends DynamicTableRenderPolicy {

	@Override
	public void render(XWPFTable table, Object data) throws Exception {
		if(data == null){
			log.error("待渲染管控事项数据为空。");
			return;
		}
		GksxTableData gksxTableData =  (GksxTableData) data;
		List<GksxRowData> problemList = gksxTableData.getGksxRowDataList();

		// 设置样式
		Style style = getStyle();
		// 循环插入行
		int startRow = 2;
		for (int i = 0; i < problemList.size(); i++) {
			// 先生成一行
			XWPFTableRow insertNewTableRow = table.insertNewTableRow(startRow+i);
			// 每一行有4列
			for (int j = 0; j < 4; j++) insertNewTableRow.createCell();

			// 封装数据
			GksxRowData gksxRowData = problemList.get(i);
			RowRenderData templateGksxRow = Rows.of(
					new TextRenderData(gksxRowData.getProblemTypeDesc(),style)
					,new TextRenderData(gksxRowData.getNum(),style),
					new TextRenderData(gksxRowData.getProblemContent(),style),
					new TextRenderData(String.valueOf(gksxRowData.getProblemScore()),style))
					.center()
					.create();
			// 渲染数据
			TableRenderPolicy.Helper.renderRow(table.getRow(startRow+i), templateGksxRow);
		}

		GksxRowData firstRowData = problemList.get(0);
		// 合并单元格
		if(firstRowData.getTypeOneSize() > 1){
			TableTools.mergeCellsVertically(table, 0, startRow, startRow+firstRowData.getTypeOneSize()-1);
		}
		if(firstRowData.getTypeTwoSize() > 1){
			TableTools.mergeCellsVertically(table, 0, startRow+firstRowData.getTypeOneSize(), startRow+firstRowData.getTypeOneSize()+firstRowData.getTypeTwoSize()-1);
		}
		TableTools.mergeCellsHorizonal(table, startRow+firstRowData.getTypeOneSize()+firstRowData.getTypeTwoSize(), 0, 2);
	}

	private Style getStyle(){
		final Style style = new Style();
		style.setFontFamily("FangSong");
		style.setFontSize(12);
		style.setBold(false);
		return style;
	}
}

测试方法:

    String filePath = "E:\\Documents\\CompanyProjects\\cxhl-services\\src\\test\\java\\word\\template\\gksx_problem.docx";
        String targetPath =  "C:\\Users\\Desktop\\output_gksx_problem.docx";
        // 初始化数据
        GksxRowData problem1 = new GksxRowData();
        problem1.setProblemTypeDesc("集团巡视审计专项检查");
        problem1.setNum("1");
        problem1.setProblemContent("测试问题描述1");
        problem1.setProblemScore(BigDecimal.ONE);
        problem1.setTypeOneSize(4);
        problem1.setTypeTwoSize(2);

        GksxRowData problem2 = new GksxRowData();
        problem2.setProblemTypeDesc("集团巡视审计专项检查");
        problem2.setNum("2");
        problem2.setProblemContent("测试问题描述2");
        problem2.setProblemScore(BigDecimal.ONE);
        problem2.setTypeOneSize(1);
        problem2.setTypeTwoSize(1);

        GksxRowData problem3 = new GksxRowData();
        problem3.setProblemTypeDesc("集团巡视审计专项检查");
        problem3.setNum("3");
        problem3.setProblemContent("测试问题描述3");
        problem3.setProblemScore(BigDecimal.ONE);

        GksxRowData problem4 = new GksxRowData();
        problem4.setProblemTypeDesc("集团巡视审计专项检查");
        problem4.setNum("4");
        problem4.setProblemContent("测试问题描述4");
        problem4.setProblemScore(BigDecimal.ONE);

        GksxRowData problem5 = new GksxRowData();
        problem5.setProblemTypeDesc("集团研发专项检查");
        problem5.setNum("5");
        problem5.setProblemContent("测试问题描述5");
        problem5.setProblemScore(BigDecimal.ONE);

        GksxRowData problem6 = new GksxRowData();
        problem6.setProblemTypeDesc("集团研发专项检查");
        problem6.setNum("6");
        problem6.setProblemContent("测试问题描述6");
        problem6.setProblemScore(BigDecimal.ONE);

        GksxRowData problem7 = new GksxRowData();
        problem7.setProblemTypeDesc("合计");
        //problem7.setNum("合计");
        problem7.setProblemContent("合计");
        problem7.setProblemScore(BigDecimal.valueOf(8.8));

        List<GksxRowData> problemList = Arrays.asList(problem1, problem2, problem3,problem4,
                problem5, problem6, problem7);

        GksxTableData gksxTableData = new GksxTableData();
        gksxTableData.setGksxRowDataList(problemList);

        JxWordExport jxWordExport = new JxWordExport();
        jxWordExport.setGksxTable(gksxTableData);
        //HashMap<String,Object> hashMap = new HashMap<>();
        //hashMap.put("gksxTable",gksxTableData);
        
        // 开始渲染
        Configure config = Configure.builder().bind("gksxTable", new TemplateGksxTablePolicy()).build();
        XWPFTemplate template = XWPFTemplate.compile(filePath, config).render(jxWordExport);
        //XWPFTemplate template = XWPFTemplate.compile(filePath, config).render(hashMap);
        template.writeToFile(targetPath);

生成效果如下:
在这里插入图片描述

注意点

  • 1、上面例子中,实体类GksxTableData对应整个表格数据,里面也可以有多个list,且render方法只会处理里面的list属性。
@Data
public class GksxTableData {
	/**
	 * 待渲染的数据 (扣分详细+合计)
	 */
	private List<GksxRowData> gksxRowDataList;

	private List<GksxRowData> testList;

}

在这里插入图片描述
testList也可以接收到,官方文档中的收费单案例就是这样实现的。

  • 2、JxWordExport(也可以不用实体类,使用HashMap替代)中的表格属性名必须和模板中的属性值相同。若行数据实体类属性添加@Name注解,则取注解的名字。

  • 3、1.10.X版本中,RowRenderData获取不到文本数据了。
    可以参考上面的案例,根据实际数据生成RowRenderData,这样代码扩展性也更强。

  • 4、表格行从head头开始算,头为0

    // 表格行从head头开始算,头为0
    table.insertNewTableRow(startRow);
    

官方文档poi-tl导出word复杂表格

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值