Java使用freemarker制作word文档完整笔记

freemarker模板引擎

1、创建一个maven项目

2、添加pom.xml依赖

1
2
3
4
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>

3、添加配置文件

方法1(推荐这种配置):

也可以在bootstrp.yml配置文件里添加配置

1
2
3
freemarker:
suffix: .ftl
template-loader-path: classpath:/staticftl

注意:需要注意缩进

img

方法2:

img

setTemplateLoaderPath 参数是指定我们定义好的模板存放目录

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.hxkj.server.api.haiyangserver.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
import java.util.HashMap;
import java.util.Map;
/**
* @Author pht
* @Description word模板配置
* @Date 2021/6/24
**/
@Configuration
public class ApplicationConfig {
@Bean(name = "freeMarkerConfigurer")
public FreeMarkerConfigurer freeMarkerConfigurer() {
FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
configurer.setDefaultEncoding("UTF-8");
configurer.setTemplateLoaderPath("classpath:/staticftl");
Map<String, Object> variables = new HashMap<>();
variables.put("xml_escape", "fmXmlEscape");
configurer.setFreemarkerVariables(variables);
return configurer;
}
}

4、模板制作

4.1 拿到原始模板文件

img

上图是一个word文件,框选的区域内容是需要程序动态填充的。然后需要整理模板格式,根据模板需要定义替换符关键字。

4.2 建立替换占位符号

创建一个txt文件

1
2
3
4
5
6
7
8
9
10
11
12
制作人
${producer}:悟空

制作日期
${cdate}:2021年11月22日

分析区域
${area1}:河北省(市)
${area2}:东海海域

分析月份
${month}:7—8

把对应需要动态替换值的位置填充上关键字,并把黄色的标注去掉

如果有图片,需要把图片插入并调整好位置。图片的替换关键字在转换成xml后做。

替换完成word文件里的占位符后,结果如下

img

模板文档中${}是占位符,即生成Word文档时占位符会被真实的数据替换。例如${name}在生成文档时会被name这个属性的值替换 ,${userObj.name}在生成文档时会被userObj这个对象的name属性的值替换。

4.3 将.doc文档另存为.xml文件

img

把word文档转成xml文件

另存为,选择xml格式

使用notepad++打开xml模板

首先格式化,需要添加xml插件

注意:另存为时选择Word2003XML文档(*.xml)

使用notepad++编辑工具打开这个xml文件

你会发现里面都是一些看不懂的乱码

此时不要慌

打开效果:

img

安装一个插件

img

使用这个插件对xml文件格式整理

img

整理完成以后变得清晰了许多

img

4.4 需要修订占位符

需要修订一下模板,用搜索Ctrl + f查询$字符,保证我们定义的占位符是完全挨着的${producer},如果看到替换关键字没有在一起,需要把中间的内容删除

img

img

4.5 拿到.xml模板后处理图片占位

配置图片的替换关键字,搜索image

把binaryData节点里面的字符串删除,改为${image1}

img

4.6 表格数据渲染配置

如果有表格

<#list list_table as list_table>

${list_table.t1} ${list_table.t2} ${list_table.t3} ${list_table.t4} ${list_table.t5}

</#list>

使用循环语句渲染比较方便。需要在<w:tr>标签的外层添加,如右图所示

<#list list_table as list_table>

</#list>

进行包裹语句块儿。

注意表格里的替换符要用#list里面定义的list_table,例如${list_table.val1}

${list_table.val2}

这里相当于从一个map对象里取出两个值。

img

所有关键字调整好后,保存,修改文件后缀为.ftl

然后放入项目对应目录下resources。模板编辑完成。

img

5、开发生成文档接口

程序主要分成3个部分

(1)准备要填充到模板里的数据

(2)把数据根据替换位置关键字打包到map对象里

(3)配置word输出位置,FreeMarker执行word生成

在Impl实现类里注入FreeMarkerConfigurer

1
2
3
4
5
FreeMarkerConfigurer freeMarkerConfigurer;
@Autowired
public void setFreeMarkerConfigurer(FreeMarkerConfigurer freeMarkerConfigurer) {
this.freeMarkerConfigurer = freeMarkerConfigurer;
}

填充模板的数据可以是前端传来的数据,也可以是从数据库获取的数据

打包map,如果有list就put一个map进去,map的key就是前面定义模板时设置的占位符。

img

图片,传递绝对地址,就可以获取图片可视化的二级支流,BASE64Encoder

img

开始生成word,需要准备的参数:

dataMap 填充模板的数据

ftlName 模板名称

docPath 输出地址+文件名

img

然后就ok了

下面是完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Override
public Result getGeneratedLetters(WeatherInfoLetters weatherInfoLetters) {
// word文档输出的目录,上传的图片也在这个目录里
String wordoutPath = "D:/xxx/";
// 测试输出地址
// wordoutPath = "D:\\ideaproject\\data\\word\\";
// 配置使用的模板名称
String templetName = "气象信息快报.ftl";
/**
* 打包数据到map
*/
Map<String, Object> templetData = dataPackage(“传入需要打包的数据”);
// 生成word文档
// 输出的文档名称
String docName = wordoutPath + "气象信息快报.doc";
// 执行生成
Boolean process = process(templetData, templetName, docName);
if (!process) {
return Result.queryIsnull("生成报表文档失败!");
}


/**
* 下面你可以根据业务做任何事,比如:需要在线预览,可以转出一份pdf提供在线预览
* 把word文档转出pdf文件,pdf文件和word使用同一个输出地址wordoutPath
*/
String outpdfname = docName.substring(0, docName.lastIndexOf("."));
Result<String> pdf = new WordToPDFUtil().wordTransformPdf(docName, outpdfname, false);
String pdfname = outpdfname.substring(1 + outpdfname.lastIndexOf("/"));

return Result.success(docName);
}

码字不易,有问题请联系我 vx:yce99867066