poi-tl(poi template language)是Word模板引擎,使用Word模板和数据创建很棒的Word文档。
poi-tl 基于 Microsoft Word 模板和 Data 生成新的 Word 文档,是 Java 中最好的 Word 模板引擎,也可能是你使用 Java 处理 Word 最中意的伙伴。
poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让人喜悦的特性。
最新文档地址 —— 点我前往
一、导入pom依赖
<dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.12.0</version> </dependency>
二、编写对应模版
我们这里需要双模版
主模版
内嵌子模版
三、编写主、子实体类
主实体类
import com.deepoove.poi.data.DocxRenderData;
import com.deepoove.poi.data.NumberingRenderData;
import com.deepoove.poi.data.PictureRenderData;
import lombok.Data;
/**
* @author DBC
*/
@Data
public class ResumeData {
private DocxRenderData experience;
private String test1;
private String test2;
private String test3;
private String test4;
}
子实体类
import com.deepoove.poi.data.NumberingRenderData;
import com.deepoove.poi.data.PictureRenderData;
import lombok.Data;
import java.util.List;
import java.util.Map;
@Data
public class ExperienceData {
private String title1;
private String title2;
private String content;
private List<Map<String, PictureRenderData>> pictures;
}
四、编写主体代码
ResumeData datas = new ResumeData();
@BeforeEach
public void init() {
datas.setTest1("测试1");
datas.setTest2("测试2");
datas.setTest3("测试3");
datas.setTest4("测试4");
// 模板文档循环合并
List<ExperienceData> experiences = new ArrayList<ExperienceData>();
ExperienceData data1 = new ExperienceData();
data1.setTitle1("第一块标题1");
data1.setTitle2("第一块图片标题2");
data1.setContent("第一块内容");
ExperienceData data2 = new ExperienceData();
data2.setTitle1("第二块标题1");
data2.setTitle2("第二块图片标题2");
data2.setContent("第二块内容");
PictureRenderData pictureRenderData1 = Pictures.ofUrl("https://www.dbc655.top/wp-content/uploads/1637587423-4.png", PictureType.PNG)
.size(100, 100).create();
PictureRenderData pictureRenderData2 = Pictures.ofUrl("https://www.dbc655.top/wp-content/uploads/img_61854270c2a64.png", PictureType.PNG)
.size(100, 100).create();
List<Map<String, PictureRenderData>> listEnd1 = new ArrayList<>();
List<Map<String, PictureRenderData>> listEnd2 = new ArrayList<>();
List<PictureRenderData> imgList = new ArrayList<>();
imgList.add(pictureRenderData1);
imgList.add(pictureRenderData2);
for (PictureRenderData imglist :imgList){
Map<String, PictureRenderData> map = new HashMap<>();
map.put("picture", imglist);
listEnd1.add(map);
}
for (int i = imgList.size() - 1;i >= 0;i--){
Map<String, PictureRenderData> map = new HashMap<>();
map.put("picture", imgList.get(i));
listEnd2.add(map);
}
data1.setPictures(listEnd1);
data2.setPictures(listEnd2);
experiences.add(data1);
experiences.add(data2);
datas.setExperience(
Includes.ofLocal("src\\main\\resources\\templates\\title1.docx").setRenderModel(experiences).create());
}
@Test
public void testResumeExample() throws Exception {
XWPFTemplate template = XWPFTemplate.compile("src\\main\\resources\\templates\\visitWordTemplate.docx").render(datas);
template.writeToFile("C:/Users/dbc/Desktop/gxyf/test.docx");
}
五、导出后具体效果
有可能出现的问题
1.POI版本比较低,但是没有办法升级POI
@Test
public void testResumeExample() throws Exception {
ResumeData datas = new ResumeData();
datas.setTest1("测试1");
datas.setTest2("测试2");
datas.setTest3("测试3");
datas.setTest4("测试4");
// 模板文档循环合并
List<ExperienceData> experiences = new ArrayList<ExperienceData>();
ExperienceData data1 = new ExperienceData();
data1.setTitle1("第一块标题1");
data1.setTitle2("第一块图片标题2");
data1.setContent("第一块内容");
ExperienceData data2 = new ExperienceData();
data2.setTitle1("第二块标题1");
data2.setTitle2("第二块图片标题2");
data2.setContent("第二块内容");
PictureRenderData pictureRenderData1 = new PictureRenderData(500, 300, ".png",
BytePictureUtils.getUrlBufferedImage("https://www.dbc655.top/wp-content/uploads/1637587423-4.png"));
PictureRenderData pictureRenderData2 = new PictureRenderData(500, 300, ".png",
BytePictureUtils.getUrlBufferedImage("https://www.dbc655.top/wp-content/uploads/1637587423-4.png"));
List<Map<String, PictureRenderData>> listEnd1 = new ArrayList<>();
List<Map<String, PictureRenderData>> listEnd2 = new ArrayList<>();
List<PictureRenderData> imgList = new ArrayList<>();
imgList.add(pictureRenderData1);
imgList.add(pictureRenderData2);
for (PictureRenderData imglist :imgList){
Map<String, PictureRenderData> map = new HashMap<>();
map.put("picture", imglist);
listEnd1.add(map);
}
for (int i = imgList.size() - 1;i >= 0;i--){
Map<String, PictureRenderData> map = new HashMap<>();
map.put("picture", imgList.get(i));
listEnd2.add(map);
}
data1.setPictures(listEnd1);
data2.setPictures(listEnd2);
Resource resource = new ClassPathResource("templates/title1.docx");
InputStream is = resource.getInputStream();
experiences.add(data1);
experiences.add(data2);
datas.setExperience(
new DocxRenderData(is, experiences));
XWPFTemplate template = XWPFTemplate.compile("src\\main\\resources\\templates\\visitWordTemplate.docx").render(datas);
template.writeToFile("C:/Users/dbc/Desktop/gxyf/test.docx");
} 具体区别老铁们就自己找了哈!不找直接粘贴也没问题![aru_43]
2.打成Jar包之后无法识别src下面的文件
org.springframework.core.io.Resource resource = new ClassPathResource("template/dbc/dbc.docx");
InputStream is = resource.getInputStream();
org.springframework.core.io.Resource resource2 = new ClassPathResource("template/dbc/dbc1.docx");
InputStream is2 = resource2.getInputStream();
dataFamilyVisitEndVO.setExperience(
new DocxRenderData(is, experiences));
XWPFTemplate template =
XWPFTemplate.compile(is2).render(dataFamilyVisitEndVO); 仅仅就是将之前传入src文件路径转换为传入流而已,没有什么大的变动
本文作者为DBC,转载请注明。


