文章目录
- 实现逻辑
- 参考代码
- 注意点
实现逻辑
自定义渲染策略实现逻辑:
- 找到模板中的表格标签
- 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 {@Overridepublic 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复杂表格