Java 采用Poi-Tl实现word导出示例

Java 采用 Poi-Tl Word模板引擎导出word表格示例

 官方poi-tl 的教程地址 :  poi-tl

 

  1. 准备一个word模板 templete.docx,放在resource文件夹下。具体路径在代码中有体现。
  2. 模板中插入表格格式2列4行就行。
  3. 编写插件类   TableRenderPolicy.java
    package com.example.demo.poitl.policy;
    
    import java.util.List;
    
    import org.apache.poi.xwpf.usermodel.XWPFTable;
    import org.apache.poi.xwpf.usermodel.XWPFTableRow;
    
    import com.deepoove.poi.data.RowRenderData;
    import com.deepoove.poi.policy.DynamicTableRenderPolicy;
    
    /**
     * @auther 作者 大有可为
     * @version 创建时间2019年7月6日下午2:40:28
     * @mail 邮箱 cdf30088@163.com
     * @weixin 微信 wxid_9w1tw6vprylc22
     * @desc 功能描述 表格内容填充 自定义插件
     */
    public class TableRenderPolicy extends DynamicTableRenderPolicy {
    
    	@Override
    	public void render(XWPFTable table, Object data) {
    		//数据强制转换一下
    		List<RowRenderData> rowList = (List<RowRenderData>) data;
           //判断要填充的数据行数是否超出现有的表格行数  超出的话 进行插入新行提前插入
    		if (rowList.size() > table.getRows().size()) {
    			for (int i = 0; i < rowList.size() - table.getRows().size(); i++) {
    				XWPFTableRow insertNewTableRow = table.insertNewTableRow(0);
    				for (int j = 0; j < 2; j++)
    					insertNewTableRow.createCell();
    			}
    		}
    		
    		//循环数据 将数据一次放入每个单元格
    		for (int i = 0; i < rowList.size(); i++) {
    			for (int j = 0; j < 2; j++) {
    				table.getRow(i).getCell(j).setText(rowList.get(i).getCellDatas().get(j).getRenderData().getText());
    			}
    		}
    	}
    }
    

     

  4. 新建一个测试类 TableRenderTest.java

    package com.example.demo.poitl;
    
    import java.io.File;
    import java.io.FileOutputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.commons.lang3.tuple.Pair;
    import org.junit.Test;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
    import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat.Enum;
    
    import com.deepoove.poi.XWPFTemplate;
    import com.deepoove.poi.config.Configure;
    import com.deepoove.poi.config.Configure.ConfigureBuilder;
    import com.deepoove.poi.data.RowRenderData;
    import com.example.demo.poitl.policy.TableRenderPolicy;
    
    /**
     * @auther 作者 大有可为
     * @version 创建时间2019年7月6日上午9:09:28
     * @mail 邮箱 cdf30088@163.com
     * @weixin 微信 wxid_9w1tw6vprylc22
     * @desc 功能描述 表格填充数据测试
     */
    public class TableRenderTest {
    	/**
    	 * ● ● ●
    	 */
    	public static final Pair<Enum, String> FMT_CHOOSE = Pair.of(STNumberFormat.NONE, "☑");
    	/**
    	 * ● ● ●
    	 */
    	public static final Pair<Enum, String> FMT_BLOCK = Pair.of(STNumberFormat.NONE, "□");
    
    	/**
    	 * @throws Exception
    	 */
    	@Test
    	public void testNumbericRender() throws Exception {
    		
    		Map<String, Object> tableDataMap = new HashMap<String, Object>();
    		
            List<RowRenderData> rowList = new ArrayList<RowRenderData>();
            new RowRenderData();
    		rowList.add(RowRenderData.build("□篮球","□足球"));
            new RowRenderData();
    		rowList.add(RowRenderData.build("□是","□否"));
            new RowRenderData();
    		rowList.add(RowRenderData.build("□玩过","□听说过"));
            new RowRenderData();
    		rowList.add(RowRenderData.build("□好开心","□好失望"));
    		
            //绑定渲染位置
            tableDataMap.put("内容", rowList);
    		ConfigureBuilder builder = Configure.newBuilder();
    		//自定义定位符
    		builder.buildGramer("${", "}");
    		//自定义插件渲染
    		builder.customPolicy("内容", new TableRenderPolicy());
    		//读取模板
    		XWPFTemplate xwpfTemplate = XWPFTemplate.compile("src/main/resources/file/word/template.docx", builder.build());
    		//渲染
    		xwpfTemplate.render(tableDataMap);
    		FileOutputStream outputStream = new FileOutputStream(new File("src/main/resources/file/export/out_template.docx"));
    		xwpfTemplate.write(outputStream);
    		outputStream.flush();
    		outputStream.close();
    		xwpfTemplate.close();
    	}
    
    }
    

     

  5. 最后导出word文档

     喜欢看源码的童鞋点一下:gitee地址

 

<think>我们正在使用poi-tl库来导出Word文档中的表格数据。根据引用,poi-tl是一个基于Apache POI的模板引擎,它允许我们通过模板和数据来生成Word文档。用户的需求是导出表格数据,可能包括循环表格和图片。 步骤: 1. 准备模板:在Word文档中创建模板,使用{{}}作为占位符,对于表格,我们可以使用循环标签。 2. 准备数据:构建一个包含表格数据的对象,该对象应该能够被poi-tl解析。 3. 使用poi-tl的API将数据填充到模板中,生成最终的Word文档。 根据引用[3],对于复杂的表格(如需要合并单元格),我们可以通过自定义数据模型来实现。例如,ServerTableData类中包含了表格行数据、分组信息和需要合并的列。 下面是一个简单的示例,展示如何使用poi-tl导出带有表格Word文档: 首先,我们需要在项目中引入poi-tl的依赖。以Maven为例: ```xml <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.10.0</version> </dependency> ``` 然后,创建一个Word模板(template.docx),在模板中定义表格的循环。例如: 在模板中,我们可以这样写: ``` 表格标题 {{#table}} 姓名 | 年龄 | 城市 {{/table}} ``` 但是,poi-tl支持更复杂的表格循环,如引用[3]中提到的循环表格行。在模板中,我们可以使用{{var}}来代表变量,使用{{#list}}...{{/list}}来循环。 更详细的模板示例(循环生成多行表格): ``` 员工信息表 姓名 年龄 城市 {{#employees}} {{name}} {{age}} {{city}} {{/employees}} ``` 注意:在Word中制作表格时,需要将循环标签放在表格的行中。 然后,在Java代码中,我们可以这样填充数据: ```java import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.data.RowRenderData; import com.deepoove.poi.data.TableRenderData; import java.io.FileOutputStream; import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public class PoiTLExample { public static void main(String[] args) throws IOException { // 准备数据 List<Object> employees = Arrays.asList( new HashMap<String, String>() {{ put("name", "张三"); put("age", "30"); put("city", "北京"); }}, new HashMap<String, String>() {{ put("name", "李四"); put("age", "25"); put("city", "上海"); }} ); // 或者使用RowRenderData(更规范,支持样式等) RowRenderData row1 = RowRenderData.build("王五", "28", "广州"); RowRenderData row2 = RowRenderData.build("赵六", "32", "深圳"); TableRenderData table = new TableRenderData(Arrays.asList(row1, row2)); // 将数据放入Map中 Map<String, Object> data = new HashMap<>(); data.put("employees", employees); // 使用Map列表的方式 // 或者使用TableRenderData // data.put("table", table); // 编译模板 XWPFTemplate template = XWPFTemplate.compile("template.docx").render(data); // 输出到文件 FileOutputStream out = new FileOutputStream("output.docx"); template.write(out); out.flush(); out.close(); template.close(); } } ``` 但是,如果表格需要合并单元格、嵌套循环等复杂操作,我们可以使用自定义渲染策略或者使用引用[3]中的方法(自定义数据模型)。 例如,引用[3]中的ServerTableData类,它包含了表格行数据、分组信息和合并列。在模板中,我们可以使用自定义标签和策略来处理。 由于poi-tl的功能非常丰富,这里只能给出一个基本示例。对于更复杂的需求,建议参考官方文档:https://github.com/Sayi/poi-tl 另外,如果需要在表格中插入图片,可以在数据模型中使用图片元素(PictureRenderData)。例如: ```java PictureRenderData picture = Pictures.ofLocal("image.png").size(100, 100).create(); data.put("image", picture); ``` 然后在模板中使用{{@image}}来插入图片。 总结步骤: 1. 制作模板:在Word中设计好表格样式,使用poi-tl的标签语法标记循环和变量。 2. 准备数据:构建一个Map,其中key是模板中的标签名,value是对应的数据(文本、表格、图片等)。 3. 编译模板并渲染数据,输出Word文档。 注意:poi-tl表格循环标签需要放在表格的行中,且循环标签内的变量放在单元格内。 如果遇到复杂表格(如合并单元格),可能需要使用自定义渲染策略,这需要更深入的学习。 由于用户的问题比较宽泛,这里给出一个基础示例。如果用户有更具体的需求(如合并单元格、循环表格且带图片),可以进一步提供解决方案。</think>### 使用 poi-tl 导出 Word 表格数据指南 #### 核心步骤 1. **准备模板文件** 创建 `.docx` 模板文件,使用 poi-tl 的标签语法定义表格结构: ```markdown | 姓名 | 年龄 | 城市 | |--------|------|---------| {{#table}} | {{name}} | {{age}} | {{city}} | {{/table}} ``` 2. **构建数据模型** ```java // 创建表格行数据 RowRenderData row1 = RowRenderData.build("张三", "25", "北京"); RowRenderData row2 = RowRenderData.build("李四", "30", "上海"); // 构建表格数据 TableRenderData table = Tables.of(new RowRenderData[]{row1, row2}) .border(BorderStyle.DEFAULT) .create(); Map<String, Object> data = new HashMap<>(); data.put("table", table); // 对应模板中的 {{#table}} 标签 ``` 3. **渲染并导出文档** ```java XWPFTemplate template = XWPFTemplate.compile("template.docx").render(data); template.writeToFile("output.docx"); ``` #### 复杂表格处理(合并单元格/嵌套表格) 参考引用 [^3] 的自定义数据模型: ```java @Data public class CustomTableData { private List<RowRenderData> rows; // 表格行数据 private Integer mergeColumnIndex; // 需要合并的列索引 private Map<String, Object> metaData; // 分组信息等 } // 使用示例 CustomTableData tableData = new CustomTableData(); tableData.setRows(Arrays.asList(row1, row2)); tableData.setMergeColumnIndex(0); // 合并第1列 ``` #### 导出含图片的表格 参考引用 [^2] 的方案: ```java // 在表格单元格中插入图片 PictureRenderData pic = Pictures.ofLocal("logo.png").size(50, 50).create(); RowRenderData imgRow = RowRenderData.build("产品图", pic); ``` #### 浏览器导出方案 ```java // Spring Boot 控制器示例 @GetMapping("/export") public void export(HttpServletResponse response) throws IOException { XWPFTemplate template = ... // 生成模板 response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document"); response.setHeader("Content-Disposition", "attachment;filename=export.docx"); template.write(response.getOutputStream()); template.close(); } ``` #### 注意事项 1. **模板标签规则**: - 行循环:`{{#row}}...{{/row}}` - 单元格变量:`{{var}}` - 避免在表格标签内使用额外空格 2. **样式控制**: ```java TableRenderData table = Tables.create(rows) .width(10000) // 表格宽度(单位: 缇) .color("FFFFFF") // 背景色 .center() // 居中对齐 ``` 3. **性能优化**: - 批量处理超过 1000 行数据时启用缓存: ```java Configure config = Configure.newBuilder().buildGramer("{{", "}}").setElMode(ELMode.SPEL_MODE).build(); XWPFTemplate.compile(templateFile, config).render(data); ``` [^1]: poi-tl 通过模板化设计简化 Word 文档生成流程 [^2]: 复杂表格和图片导出需结合自定义数据模型 [^3]: 单元格合并需指定合并列索引并预处理数据
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值