/poi-tl-plus

( Docx - Microsoft Word Template Process) Enhancement to POI-TL (https://github.com/Sayi/poi-tl). Support defining Table templates directly in Microsoft Word (Docx) file.

Primary LanguageJavaApache License 2.0Apache-2.0

poi-tl-plus

Enhancement to POI-TL (https://github.com/Sayi/poi-tl).
Support defining Table templates directly in Microsoft Word (Docx) file.

POI-TL的 MiniTableRenderData 可以支持简单的表格,但是表格样式和内容的样式无法在 Word 中直接定制.  

POI-TL 还提供了 DynamicTableRenderPolicy 支持把需要动态渲染的部分单元格交给自定义模板渲染策略,
但是样例提供的程序代码只适用于此特定的样例,不是通用的代码.   

如果想在你自己的业务模块中, 也实现动态渲染的部分单元格交给自定义模板渲染策略, 避免不了写代码来操作word文件.  

鉴于此, 此 Repository 把动态渲染的部分单元格交给自定义模板渲染策略抽象出来,做成了通用的 Table 渲染策略,
期望适用于大部分自定义表格模板的场合.  

Maven 依赖:  
除了依赖 poi-tl (请参见 https://github.com/Sayi/poi-tl ) 之外,
只额外依赖 lombok (你也可以去掉,自己补全代码里面的 getter/setter 方法即可), 

Features:
1. 常见表格的定义完全可以实现在 Word 中定义: 完全所见即所得的在 Word 文档中定义表格的表头和样式,   
数据行的单元格和样式,设置数据行每列的绑定字段, 即可实现表格的自动生成.  

2. 表格中,除了可以绑定到来自数据库的源数据之外,还可增加行号列, 自动渲染出行号值.  

3. 完全兼容 POI-TL 已有的功能. 比如支持多文档合并, 每个文档内都可以使用动态表格渲染策略来渲染不同的多个表格.  


具体样例如下:   
1) Word模板以及表格的定义:  
* 模板主文档(projectTemplate.docx), 可以看到里面POI-TL的各自常用标签都可以使用,
而且表格可以自由定义包括样式 (包括底色,对齐,字体以及字体颜色等等),
注意: 
  在一个文档中, 可以添加多个表格,每个表格都可以绑定到不同的数据集上;
  表格的数据绑定: 例如 {{teamMembers}} 就把对应的表格绑定到下面 Java代码里的 teamMembers 集合上.
  表格各列的数据绑定: 在数据行的单元格里,使用 ==fieldName 即可绑定到表格数据的字段上.
  特别地, 使用 ==ROW_NUM 可以绑定到内置的自动生成的行号字段.
  
(贴图: https://github.com/wujianbin-sh/poi-tl-plus/blob/master/projectTemplateDocx.jpg )
 

* 子文档模板 projectMilestoneTemplate.docx, 同上,可以使用 POI-TL库和本库提供的表格标签做数据绑定:
(todo: 贴图)

2) Java 代码准备数据模型:  
  // suppose data relationships are:       
  // 1:N project -> team members : project.getTeamMembers();     
  // 1:N project -> stake holders: project.getStakeholders();     
  // 1:N project -> milestones: project.getMilestones();     
  // 1:N milestone -> deliverables: milestone.getDeliverables();   

  // first get your data from Database(or somewhere else)   
  List projectData = projectDao.getById(projectId);   

  String outputFile = "outputFile.docx";   
  String projectTemplateFile = "Project.docx";   
  String milestoneTemplateFile = "projectMilestone.docx";   

  int startRow = 1;   

  // For each Table in the Docx template: define its TableRowRenderPloicy  
  TableRowRenderPloicy teamMemberTablePloicy = new TableRowRenderPloicy("teamMembers", startRow);   
  TableRowRenderPloicy stakeholderTablePloicy = new TableRowRenderPloicy("stakeholders", startRow);   
  TableRowRenderPloicy deliverableTablePloicy = new TableRowRenderPloicy("deliverables", startRow);     

  //Prepare data model for Docx template data binding:  
  @SuppressWarnings("serial")  
  Map data = new HashMap() {{  
    // for Project.docx: that's the master Docx template  
    put("project", projectData);   
    put(teamMemberTablePloicy.tableKey, projectData.getTeamMembers());   
    put(stakeholderTablePloicy.tableKey, projectData.getStakeholders());   


    // for projectMilestone.docx: that's the sub Docx template for each of project Milestones  
    DocxRenderData projectMilestonesDoc = new DocxTableRenderData(milestoneTemplateFile,
      projectData.getMilestones(), 
      (milestone)->{  
        return new HashMap() {{  
            put("milestone", milestone);   
            put(deliverableTablePloicy.tableKey, ((Milestone)milestone).getDeliverables());   
        }};   
    });   

    // add sub docx template data into master docx template data:  
    put("projectMilestonesDoc", projectMilestonesDoc);   
  }};   

  try {  
    // generate docx now: outputFile.docx will be generated  
    DocxTableRenderPolicy.renderDocx(projectTemplateFile, outputFile, data,    
      teamMemberTablePloicy, stakeholderTablePloicy, deliverableTablePloicy);     
  } catch (Exception e) {  
    e.printStackTrace();   
  }  


3) 渲染的结果(生成的文档):  
(todo: 贴图)