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

实现逻辑

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

  • 找到模板中的表格标签
  • 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复杂表格

相关推荐

  1. 【 Vue 】定义渲染器和异步渲染

    2024-04-28 20:46:03       17 阅读
  2. kafka定义分区策略详解

    2024-04-28 20:46:03       30 阅读
  3. Ant Design Vue Table 定义渲染定义单元格

    2024-04-28 20:46:03       13 阅读
  4. Pod中使用定义服务账号调用定义资源

    2024-04-28 20:46:03       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-28 20:46:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-28 20:46:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-28 20:46:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-28 20:46:03       18 阅读

热门阅读

  1. MySQL详细步骤及案列

    2024-04-28 20:46:03       12 阅读
  2. maya 设置半径 获取时长,设置时长

    2024-04-28 20:46:03       12 阅读
  3. react写一个从下往上划出的弹框弹窗组件

    2024-04-28 20:46:03       10 阅读
  4. redis 键常用命令

    2024-04-28 20:46:03       11 阅读
  5. AI作画算法原理详解

    2024-04-28 20:46:03       10 阅读
  6. [GN] 车300笔试记

    2024-04-28 20:46:03       10 阅读
  7. Linux制作docker镜像

    2024-04-28 20:46:03       12 阅读
  8. 前端初学者必读的 Web Workers指南

    2024-04-28 20:46:03       11 阅读