JAVA通过freemarker实现自动填充word文档
一.需求背景
甲方提供了word格式的报告模板,我方需要通过业务系统中的数据自动把报告模板中的内容填充完整,生成一份word报告,以代替人力去系统中查找数据并手动填充word报告模板.
二.技术方案
通过freemarker模板引擎实现:
- 通过word文档编写出可供freemarker读取的**.ftl模板
- java代码引入freemarker依赖,读取**.ftl模板并将数据整理填充,通过io流输出文件
- 将输出的文件加工成word文档
三.具体实现
1.编写ftl模板
将客户提供的word模板解压缩,会得到以下四个文件(夹),进入word文件夹,找到document.xml.此文件即word文档中我们要编写的内容.将此文件剪切出并打开.
打开后找到我们在word文档中标记的占位符,将其使用${}包裹,即可实现模板的基本编辑.
多数情况下,我们需要对表格进行填充,这就涉及到了list循环,其实也是一样的道理,找到我们占位符的父标签,并用<#list arrayList as item><#list>标签进行包裹即可,具体如图:
同时,ftl支持if…else等多种判断,也支持字体,颜色,格式等修改 应用比较灵活
此时,一个ftl模板就做好了
2.java代码实现模板字段填充
引入freemarker依赖包
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
实现逻辑:
package com.jscoe.core.commons.util;
import com.google.common.collect.Lists;
import com.jscoe.core.modules.ftl.entity.Drafter;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;
import java.io.*;
import java.time.Instant;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
@Log4j2
public class FtlUtil {
private static final String ENCODING = "UTF-8";
private static final String outFilePath = "E:\\****\\result\\document.xml";
public void test() throws Exception {
// 第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是FreeMarker对于的版本号。
Configuration configuration = new Configuration(new Version("2.3.23"));
// 第二步:设置模板文件所在的路径。
configuration.setDirectoryForTemplateLoading(new File("E:\\****"));
// 第三步:设置模板文件使用的字符集。一般就是utf-8.
configuration.setDefaultEncoding("utf-8");
// 第四步:加载一个模板,创建一个模板对象。
Template template = configuration.getTemplate("document.ftl", ENCODING);
// 第五步:创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。
List<Drafter> drafterArrayList = Lists.newArrayListWithCapacity(5);
for (int i = 0; i < 5; i++) {
drafterArrayList.add(Drafter.builder()
.department("总裁办"+i+"")
.postion("ceo"+i+"")
.name("老王"+i+"")
.sign("哈哈哈哈"+i+"")
.data(Instant.now()).build());
}
Map dataModel = new HashMap<>();
//向数据集中添加数据
dataModel.put("drafterList", drafterArrayList);
// 第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。
Writer out = new OutputStreamWriter(new FileOutputStream(outFilePath), ENCODING);
// StringWriter stringWriter = new StringWriter();
// 第七步:调用模板对象的process方法输出文件。
template.process(dataModel, out);
// String resultStr = stringWriter.toString();
// System.out.println(resultStr);
// 第八步:关闭流。
out.close();
}
}
使用io流,将填充好的xml格式的模板放回一开始获取document.xml的地方,然后将解压得到的四个文件压缩为zip格式的压缩文件,更改格式为docx即可看到填充后的word报告.这部分功能可以借助hutool工具进行解压缩操作实现.
效果如下:
完美!