前言-Freemarker简单介绍
- 近期项目工作中需要编写大量格式相同但数据不同的Word文档,需要实现自动生成文档的效果,但是通过网上冲浪和官方文档搜索,相对来说,没有分类整理的文档,因此自己抽空简要分类整理了一下,如果错误,还请各位reader尽情指出。
0 环境准备
- 这里提供一个基础SpringBoot项目,后续的每个环节的代码都将一步步以这个为基础构建,如果你也打算从头开始挨个实操一遍,可以下载并导入之后同步我的后续操作,文末也会提供一份完整的代码
- 链接:https://www.aliyundrive.com/s/iXoQuRZh9pf
- 环境配置说明
- IDEA2019.3
- JDK1.8
- SpringBoot2.3.7.RELEASE
- Freemarker 2.3.28
- 目录结构介绍
- src下存储主要的代码,这里划分了六个包,分别是text(普通文本)、object(对象)、picture(图片)、table(表格)、attachment(附件)、utils(工具类),之所以将每个不同类型的操作分开,是因为考虑到看到此篇文章的reader都有各自不同的需求,这样就可以直接定位到自己需要的模块,如果需要不同类型的组合,只需要弄清楚每一块的数据存储和映射就可以做到自己按需拼凑了。建议看一下处理普通文本模块,里面一些内容在后续其他模块不会重复赘述
- resource下面也针对五大类型设置了五个文件夹,其中每个文件的名字和src下的包名是对应的,其中template文件夹存储模板文件(doc、xml、ftl文件),generate保存根据对应模板生成的最终文件
- pom.xml中没有比较特别的,引入了Freemarker的依赖
1 处理普通文本
-
准备Word文档
- 在resources/freemarker/text/template文件夹下,创建一个text.doc文件,文件内容如下
-
保存为xml格式
- doc文档编写完成之后,使用另存为,保存为xml格式(WPS)
- 保存的时候需要注意以下两点
- 保存位置,我这里都是存储在template同样目录下
- 保存格式选择
-
转换为ftl格式
- 使用一些强大的文本编辑工具(这里使用EditPlus),打开xml文件,进行格式化
- 格式化xml工具:https://blog.youkuaiyun.com/qq_41649001/article/details/119595800
- 格式化前后对比
- 如果格式化后,出现${}形式的占位符中的内容被分隔开了,如下面情况,那么我们需要手动删除掉中间内容即可
- 我们可以使用ctrl+f就可以搜索到我们在doc文档中填写的${}形式的占位符,后续Freemarker会识别占位符,然后进行替换
- 然后另存为为ftl格式文件即可
- 到现在为止,我们的模板文件已经准备好了(ftl),其他两个文件可以看做是过渡文件
- 使用一些强大的文本编辑工具(这里使用EditPlus),打开xml文件,进行格式化
-
编写代码
- 编写一个Freemarker生成Word文档的工具类,减少代码冗余,以后的一些生成操作直接调用即可,放在src中utils包中
package com.fc.fcleverutils.freemarker.utils; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.Version; import java.io.*; import java.util.Map; /** * @ClassName WordUtil * @Description 使用Freemarker生成Word文档工具类 * @Author Fclever * @Date 2021/8/11 10:06 **/ public class WordUtil { /** * 使用Freemarker自动生成Word文档 * @param dataMap 保存Word文档中所需要的数据 * @param templatePath 模板文件的绝对路径 * @param templateFile 模板文件的名称 * @param generateFile 生成文件的路径+名称 * @throws Exception */ public static void generateWord(Map<String, Object> dataMap, String templatePath,String templateFile, String generateFile) { // 设置FreeMarker的版本 Configuration configuration = new Configuration(new Version("2.3.28")); // 设置Freemarker的编码格式 configuration.setDefaultEncoding("UTF-8"); Writer out = null; try{ // 设置FreeMarker生成Word文档所需要的模板的路径 configuration.setDirectoryForTemplateLoading(new File(templatePath)); // 设置FreeMarker生成Word文档所需要的模板名称 Template t = configuration.getTemplate(templateFile, "UTF-8"); // 创建一个Word文档的输出流 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(generateFile)), "UTF-8")); //FreeMarker使用Word模板和数据生成Word文档 t.process(dataMap, out); } catch (Exception e) { e.printStackTrace(); } if (out != null) { try { out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
- 然后在启动类中,编写获取数据代码和调用生成Word文档的工具方法
package com.fc.fcleverutils; import com.fc.fcleverutils.freemarker.utils.WordUtil; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import java.util.HashMap; import java.util.Map; @SpringBootApplication public class FcleverUtilsApplication { public static void main(String[] args) { SpringApplication.run(FcleverUtilsApplication.class, args); // 1. 使用Freemarker生成Word文档(普通文本) WordUtil.generateWord(getTextData(), "G:\\IdeaProjects\\FcleverUtils\\src\\main\\resources\\freemarker\\text\\template\\", "text.ftl", "G:\\IdeaProjects\\FcleverUtils\\src\\main\\resources\\freemarker\\text\\generate\\text.doc"); } /** * 获取生成普通文本所需数据 * @return */ private static Map<String, Object> getTextData() { /* * 创建一个Map对象,将Word文档需要的数据都保存到该Map对象中 */ Map<String, Object> dataMap = new HashMap<>()