SpringBoot导出Word⽂档(docdocx)Office⽆法打开,WPS正常等坑
⾸先引⼊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.Class(), "/");
ClassPathResource classPathResource =new ClassPathResource("/files/");
configuration.File());
//设置对象包装器
configuration.setObjectWrapper(new DefaultObjectWrapper(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS));
//设置异常处理器
configuration.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
//获取ftl模板对象
Template template = Template("template.ftl");
//输出⽂档
StringBuilder fileName =new StringBuilder("啦啦啦啦.doc");
//            if (StringUtils.StudentName())) {
//                fileName.StudentName()).append("的简历").append(".doc");
//            } else {
//                fileName.append("默认简历").append(".doc");
//            }
try{
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition","attachment;filename="
+new String().getBytes("GBK"),"ISO-8859-1"));
response.setCharacterEncoding("utf-8");//处理乱码问题
//⽣成Word⽂档
template.process(dataMap, Writer());
}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 = InputStream();
data =new byte[in.available()];
in.close();
}catch(IOException e){
e.printStackTrace();
}
// 对字节数组Base64编码
BASE64Encoder encoder =new BASE64Encoder();
// 返回Base64编码过的字节数组字符串
quireNonNull(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是⽆法打开的。
转义字符对应的特殊符号:< 对应< , >;对应> , &;对应&无法打开文件
后记