首先先上成功的代码,然后再讲碰到的各种问题
- 导入freemarker的maven坐标
<!--freemarker 生成word-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
- 新建一个freemarker的配置类
这里我数据里有特殊字符,特地设置了< > # @ \ / 等自动转义
package com.demo.app.config.freemarker;
import freemarker.core.XMLOutputFormat;
import freemarker.template.Configuration;
import org.springframework.context.annotation.Bean;
/**
* @program: demo
* @description:
* @author: fbl
* @create: 2021-12-23 14:19
**/
@org.springframework.context.annotation.Configuration
public class WordConfig {
@Bean
public Configuration wordConfiguration(){
Configuration result = new Configuration();
result.setDefaultEncoding("utf-8");
//设置模板加载器
result.setClassForTemplateLoading(this.getClass(), "/word");
// 设置Freemarker格式化模板 > < 等特殊符号转义
result.setOutputFormat(XMLOutputFormat.INSTANCE);
return result;
}
}
- 接下来整理模板
3.1 新建一个word,将数据填充在需要的位置,如下图
3.2 将word另存为xml文件,再接着改名为ftl文件后缀,粘贴到项目中,路径在上面的配置代码中有,是根目录下的word文件夹中
这个ftl文件实际就是xml文件,里面好多数据还需要处理一下,需要用到freemarker语法
例如:
// 符号转义
比较:> gt,< lt,<= lte, >= gte
// 处理列表循环取出数据 相当于for
<#list data.elementDetails as detali></#list>
// 另一种循环 相当于fori
<#list 1..(data.elementDetails!?size-1) as i>
// 集合的长度
empList?size
// 跳出循环
<#break>
// 取出数组下标相符的数据
${data.elementDetails[0].num!}
// if判断决定值是什么
<#if data.stable.stableFlag>稳定<#else>不稳定</#if>
// 非空判断 ??
<#if data.biology??>${data.biology.poison!""}</#if>
// 字符串包含
<#if t.safetyCheck?contains("5")> ...操作</#if>
- 接下来是service层用数据渲染模板,controller就是调service没有什么可写的
@Resource(name = "wordConfiguration")
private Configuration wordConfiguration;
public void wordExport(HttpServletResponse response, Integer id){
// 搜集需要导出的数据
MsdsWordExportDto wordData = getWordData(id);
// 枚举数据处理
parseWordData(wordData);
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("data", wordData);
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=chemical.doc");
//加载模板
try {
Template template = wordConfiguration.getTemplate("化学品安全技术说明书模板测试.ftl", "utf-8");
template.process(dataModel, response.getWriter());
} catch (Exception e) {
e.printStackTrace();
}
}
更新一下生成word文档中带图片怎么办
- 首先新建一个word文档,里面有张图片
- 接着另存为xml,改名ftl(上述操作)
- 找到ftl文件存储图片的地方,是base64格式的密文
把它改为你传入的参数,当然参数也要是base64格式的字符串
以下是转换base64的代码,传入的参数是图片的url,类似于:http://172.16.0.72:8003/file/1.jpg
/**
* 图片导出word 使用base64
*
* @param imgFile
* @return
*/
private String getImgFileToBase64(String imgFile) {
//将图片文件转化为字节数组字符串,并对其进行Base64编码处理
byte[] buffer = null;
// 获取图片路径
int lastIndexOf = imgFile.lastIndexOf('/');
String fileName = imgFile.substring(lastIndexOf + 1);
String filePathString = path + fileName;
//读取图片字节数组
try (InputStream inputStream = new FileInputStream(filePathString)){
buffer = new byte[inputStream.available()];
inputStream.read(buffer);
} catch (IOException e) {
e.printStackTrace();
}
// 对字节数组Base64编码
return new BASE64Encoder().encode(buffer);
}
又做了一个freemarker导出work多图片的,又加深了理解
在这里插入base64之后
上面会有引用
搜索id,发现word中引用这张图片