以下对于生成doc文档来说哒,
对于生成docx请移步https://blog.csdn.net/wantLight/article/details/106105416
首先引入freemarker依赖
<!--引入freemarker 模板依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
示例Controller:
@RequestMapping(value = "/export", method = RequestMethod.GET)
public void downloadWord(HttpServletRequest request, HttpServletResponse response) {
try {
// 告诉浏览器用什么软件可以打开此文件
response.setHeader("content-Type", "application/msword");
// 下载文件的默认名称
response.setHeader("Content-Disposition", "attachment;filename=xx分析.doc");
Map<String, Object> dataMap = detailService.showWordDetail();
//创建配置实例对象
Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
//设置编码
configuration.setDefaultEncoding("UTF-8");
//加载需要装填的模板
//configuration.setClassForTemplateLoading(this.getClass(), "/");
ClassPathResource classPathResource = new ClassPathResource("/files/");
configuration.setDirectoryForTemplateLoading(classPathResource.getFile());
//设置对象包装器
configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS));
//设置异常处理器
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
//获取ftl模板对象
Template template = configuration.getTemplate("template.ftl");
//输出文档
StringBuilder fileName = new StringBuilder("啦啦啦啦.doc");
// if (StringUtils.isNotEmpty(data.getStudentName())) {
// fileName.append(data.getStudentName()).append("的简历").append(".doc");
// } else {
// fileName.append("默认简历").append(".doc");
// }
try {
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename="
+ new String(fileName.toString().getBytes("GBK"), "ISO-8859-1"));
response.setCharacterEncoding("utf-8");//处理乱码问题
//生成Word文档
template.process(dataMap, response.getWriter());
} catch (Exception e) {
e.printStackTrace();
} finally {
response.flushBuffer();
}
} catch (Exception e) {
e.printStackTrace();
}
}
word里面生成图片需要将图片转Base64:
/**
* 本地图片转换Base64的方法
*
* @param imgPath
*/
public static String imageToBase64(String imgPath) {
byte[] data = null;
// 读取图片字节数组
try {
ClassPathResource classPathResource = new ClassPathResource(imgPath);
InputStream in = classPathResource.getInputStream();
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
// 返回Base64编码过的字节数组字符串
return encoder.encode(Objects.requireNonNull(data));
}
我的模板/图片路径都在resources/files下:对应传imgPath = files/图3.jpeg

需要替换的元素用${xxxxxx}占位符在word里替换了,如果有多条数据则添加<#list userList as user><#list>标签,userList是Map里的key。
注意:符号字体格式一定要保持一致,否则会出现转xml后分隔的问题

比较好的办法是:doc中先不写变量,将doc转成xml,然后用doc打开这个xml,这时候加变量就好了,${name}就不会被分离了。建议使用notepad++,借助插件可以自动格式化xml文档
注意:使用wps保存xml时要保存xml格式(03版的doc格式),否则会出现office 打不开的情况(或者图片无法加载)

图片出不来还有可能是w:name的后缀名与实际不符合,加${picStyle}替换后缀名~,还要注意前后标签要顶着你的占位符,不要换行或者有空白!!!

其它
特殊字符的处理:
ftl模板导出word时,如果填充的字符含有特殊字符< 、>、&,那么导出的word是无法打开的。
转义字符对应的特殊符号:< 对应< , >对应> , &对应&
后记
由于导出的doc格式太旧啦,这里需要将doc换成docx(同样使用freemarker的方式)。见我下一篇博客
https://blog.csdn.net/wantLight/article/details/106105416
本文介绍了在SpringBoot项目中使用Freemarker模板引擎生成Word(docdocx)文档时遇到的坑,如Office无法打开、WPS正常、图片加载问题及特殊字符处理。解决方案包括正确保存XML格式、处理图片Base64编码、避免字体格式不一致导致的分隔问题,以及转义特殊字符。同时提醒注意doc到docx格式转换的方法。

413

被折叠的 条评论
为什么被折叠?



