poi-tl的使用(最全详解)
Posted JavaSupeMan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poi-tl的使用(最全详解)相关的知识,希望对你有一定的参考价值。
概述
poi-tl,简单的说,就是通过一些标记,如text,@image等,放到你指定的word模板里,然后去读取替换这些值,再输出填充数据后的word,可以做生成报表的功能
一、引入pom
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.10.0</version>
</dependency>
注意apache.poi版本要对应
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
二、准备工作
在D盘,自己创建两个文件夹,一个是用来存储模板文件,另一个是用来存储生成的文件
我这里是在D盘
D:\\data\\template 存放模板
D:\\data\\word 存放生成的文件
三、案例走起
案例一 :普通文本及图片的渲染
1.准备一个word模板,命名为test1.docx,放到D:\\data\\template 下
注意,是官方指定的格式,可以查看官网,当然也可以自定义,这个后面来讲
2.编写生成代码
@PostMapping(value = "/testdoc01")
public void Tx01() throws IOException
//存放要填充的数据
Map<String, Object> datas = new HashMap<String, Object>();
//模板地址
String templateFilePath = "d:/data/template/";
//生成文件的保存地址
String destFilePath = "d:/data/template/word";
//文字 这里介绍两种数据填充方式
//1.可以设置一些通用样式
Style style = Style.builder().buildUnderlineColor("00FF00").buildFontSize(18).buildColor("00FF00").build();
datas.put("var1", Texts.of("内容1").style(style).create());
datas.put("var2", Texts.of("超链接").link("http://deepoove.com").style(style).create());
//2.文字可以通过Texts创建,也可以使用对象new TextRenderData("000000", "Sayi")
datas.put("var3",new TextRenderData("000000", "内容3"));
//图片
datas.put("image", Pictures.ofUrl("http://deepoove.com/images/icecream.png")
.size(100, 100).create());
//渲染文件
XWPFTemplate compile = XWPFTemplate.compile(templateFilePath + "test1.docx");
compile.render(datas);
//输出为文件,指定输出文件名
compile.writeToFile(destFilePath+"out_test01.docx");
3.调用后,查看生成的文件
案例二:表格的渲染,表格合并
1.准备一个word模板,命名为test2.docx,放到D:\\data\\template 下
2.编写生成代码
@PostMapping(value = "/Tx02")
public void Tx02() throws IOException
//存放要填充的数据
Map<String, Object> datas = new HashMap<String, Object>();
//模板地址
String templateFilePath = "d:/data/template/";
//生成文件的保存地址
String destFilePath = "d:/data/template/word";
//RowRenderData就是指定每一行数据的,可以去官网查阅,这里相当于设置了三行,row0就是表头,row1,row2是表内容
RowRenderData row0 = Rows.of("姓名", "学历").textColor("FFFFFF")
.bgColor("4472C4").center().create();
RowRenderData row1 = Rows.create("李四", "博士");
RowRenderData row2 = Rows.create("李四", "博士");
datas.put("var1", Tables.create(row0, row1,row2));
//合并单元格
RowRenderData roW0 = Rows.of("列0", "列1", "列2", "列3").center().bgColor("4472C4").textColor("7F7f7F").textFontFamily("Hei").textFontSize(15).create();
RowRenderData roW1 = Rows.create("没有数据", null, null, null);//第一行
//合并第几行第几列 到 第几行第几列
MergeCellRule rule = MergeCellRule.builder().map(MergeCellRule.Grid.of(1, 0), MergeCellRule.Grid.of(1, 2)).build();
datas.put("var2", Tables.of(roW0, roW1).mergeRule(rule).create());
//渲染文件
XWPFTemplate compile = XWPFTemplate.compile(templateFilePath + "test2.docx");
compile.render(datas);
//输出为文件,指定输出文件名
compile.writeToFile(destFilePath+"out_test2.docx");
3.调用后,查看生成的文件
案例三:动态表格的生成
1.准备一个word模板,命名为test3.docx,放到D:\\data\\template 下
2.编写生成代码
//模板地址
String templateFilePath = "d:/data/template/";
//生成文件的保存地址
String destFilePath = "d:/data/template/word";
Map<String, Object> datas = new HashMap<String, Object>();
Student student1 = new Student();
student1.setAge("12");
student1.setIndex("1");
student1.setName("张三");
student1.setSex("男");
Student student2 = new Student();
student2.setAge("122");
student2.setIndex("11");
student2.setName("张三1");
student2.setSex("男1");
List<Student> studentList = List.of(student1,student2);
datas.put("lists",studentList);
// 插件列表,可以去官网查看,有列循环,还有行循环,这里是行循环实例
LoopRowTableRenderPolicy policy = new LoopRowTableRenderPolicy();
//这里可以指定一个config类,用来指定一些规则,也可以改变模板中的这种格式
Configure config = Configure.builder()
.bind("lists", policy).build();
XWPFTemplate compile = XWPFTemplate.compile(templateFilePath + "test3.docx",config);
compile.render(datas);
compile.writeToFile(destFilePath+"out_test3.docx");
3.调用后,查看生成的文件
案例四:结构体的应用
简述:结构体的应用,说白了,就是指定模板中的某一块内容,然后通过多个map,可以对这一块进行渲染,也就渲染出了多个这块的内容
1.准备一个word模板,命名为test4.docx,放到D:\\data\\template 下
2.编写生成代码
@PostMapping(value = "/Tx03")
public void Tx03() throws IOException
//模板地址
String templateFilePath = "d:/data/template/";
//生成文件的保存地址
String destFilePath = "d:/data/template/word";
Map<String,Object> map = new HashMap<>();
Map<String,Object> map1 = new HashMap<>()
put("tex1","hhhhh11");
;
Map<String,Object> map2 = new HashMap<>()
put("tex1","hhhhh22");
;
List<Map<String,Object>> maps = Arrays.asList(map1,map2);
map.put("tests",maps);
map.put("tex2","哈哈");
ConfigureBuilder builder = Configure.builder();
XWPFTemplate compile = XWPFTemplate.compile(templateFilePath + "test4.docx",builder.build());
compile.render(map);
compile.writeToFile(destFilePath+"out_test4.docx");
3.调用后,查看生成的文件
以上就是一些简单的例子了,上面都是输出的文件,当然也可以已流的形式输出,用于文件下载
只需要修改一个地方
五、结构体应用升级版,使用对象作为数据源
1.准备一个word模板,命名为test4.docx,放到D:\\data\\template 下
2.编写生成代码
渲染的对象
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class WarningData
private List<ExperienceData> experiences;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class ExperienceData
private String title;
private String error;
//渲染图片的对象
private PictureRenderData pictureRenderData;
这里就是封装的传入参数,warningData就是上面的对象
default void generateWordStream(ServletOutputStream outputStream, String templateFilePath, Object WarningData ) throws IOException
File file = new File(templateFilePath);
if(!file.isFile())
throw new BizException(CodeMsg.FILE_NOT_EXIST_ERROR.fillArgs("模板文件不存在!"+file.isFile()+" "+templateFilePath));
ConfigureBuilder configureBuilder = Configure.builder();
XWPFTemplate.compile(templateFilePath,configureBuilder.build())
.render(WarningData)
.write(outputStream);
poi-tl动态遍历
最近工作需要导出word文档,选择使用了poi-tl这个word模板引擎
官网文档 Poi-tl Documentation
在使用过程中需要动态遍历一个集合数据,可以使用ListRenderPolicy这个插件,但是官方文档不知为何没有写出具体实例,但是在源码里是可以找到的相应的实例
源码地址
这里我自己写个测试实例以作记录
poi-tl版本
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.10.1</version>
</dependency>
-
具体代码:
@Data public class WordVO private List<PictureRenderData> picture; private String problem; private String reason;
package com.twy.controller; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.PictureRenderData; import com.deepoove.poi.data.TextRenderData; import com.deepoove.poi.policy.ListRenderPolicy; import com.twy.entity.WordVO; import org.apache.commons.collections4.CollectionUtils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @RestController public class TestController @GetMapping("/download") public void download() throws IOException Map<String, Object> map = new HashMap<String, Object>(); InputStream inputStream = Thread.currentThread().getContextClassLoader() .getResourceAsStream("template/test.docx"); ListRenderPolicy policy = new ListRenderPolicy(); Configure config = Configure.builder().bind("pictures", policy).build(); List<WordVO> detailList = new ArrayList<>(); WordVO one = new WordVO(); WordVO two = new WordVO(); one.setProblem("问题测试1"); two.setProblem("问题测试2"); one.setReason("原因测试1"); two.setReason("原因测试2"); List<PictureRenderData> pList1 = new ArrayList<>(); List<PictureRenderData> pList2 = new ArrayList<>(); String location = System.getProperty("user.dir") + "/poi-tl/src/main/resources/"; pList1.add(new PictureRenderData(100, 120, location + "img/1.jpg")); pList1.add(new PictureRenderData(100, 120, location + "img/2.jpg")); pList2.add(new PictureRenderData(100, 120, location + "img/3.jpg")); one.setPicture(pList1); two.setPicture(pList2); detailList.add(one); detailList.add(two); List<Object> list = new ArrayList<>(); detailList.forEach(wordVO -> list.add(new TextRenderData(wordVO.getProblem())); list.add(new TextRenderData(wordVO.getReason())); if (CollectionUtils.isNotEmpty(wordVO.getPicture())) list.addAll(wordVO.getPicture()); ); map.put("pictures", list); XWPFTemplate template = XWPFTemplate.compile(inputStream, config).render(map); template.writeToFile(location + "result/test.docx");
代码结构目录:
- word模板
- 导出结果
以上是关于poi-tl的使用(最全详解)的主要内容,如果未能解决你的问题,请参考以下文章
深入Java微服务之网关系列4: SpringCloud gateway详解(史上最全)