Java通过word模板导出word
1.创建word模板文件,注意调整好格式,后期修改较为麻烦
2.打开创建好的word模板,点击文件另存为,选择xml格式

4.在项目中引入freemarker依赖
5.将模板.ftl文件放入项目resources下面的templates(自定义文件夹)
6.编写代码程序。 示例如下:
public void exportReport(HttpServletResponse response) throws IOException, TemplateException {
//map存储word需要的数据
Map<String, Object> dataMap = new HashMap<>();
//封装好的数据
ReportDataDto dataForWord = getDataForWord(taskNo, isExport);
//将数据指定key存储到map中
dataMap.put("reportData", dataForWord);
//配置对象
Configuration configuration = new Configuration();
//设置配置的字符编码为utf-8,避免字符集问题
configuration.setDefaultEncoding("UTF-8");
//获取resources下指定的文件夹路径,如果项目需要打成jar包,
//此举很重要,别的方式可能无法获取到模板文件夹的相对路径
configuration.setClassForTemplateLoading(this.getClass(), "/templates");
// 获取模板实例,上行配置了模板文件所在路径
Template t = configuration.getTemplate("模板.ftl", "utf-8");//以utf-8的编码读取ftl文件
//设置响应类型为word
response.setContentType("application/msword");
//设置响应头,注意如果导出的word名含有汉字则需要将文件名
//变成byte并且指定字符集为gbk,表示将GBK汉字转为byte
//然后将其转为iso8859-1的字符串
response.setHeader("Content-Disposition", "attachment;filename=\""
+ new String(("导出报告").getBytes("GBK"), "iso8859-1") + "\"");
//此句非常关键,不然word文档全是乱码
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
//使用数据填充模板
t.process(dataMap, out);
//以流的输出到浏览器,即下载
out.close();
}
7.使用freemarker标签对模板.ftl文件进行数据渲染,例如:

tip:
1.<w:p>代表xml的段落,<w:r>代表行,<w:t>代表文本内容
2.对于word中存在图片的情况,生成的模板.ftl将有这样一部分:

需要先将图片转为base64,下面提供一种方式
public class Base64Util {
/**
*通过图片的URL转为base64
*/
public static String getBase64ByImgUrl(String url){
String suffix = url.substring(url.lastIndexOf(".") + 1);
try {
URL urls = new URL(url);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Image image = Toolkit.getDefaultToolkit().getImage(urls);
BufferedImage biOut = toBufferedImage(image);
ImageIO.write(biOut, suffix, baos);
String base64Str = encodeImage(baos.toByteArray());
return base64Str;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 图片转字符串
* @param image
* @return
*/
public static String encodeImage(byte[] image){
BASE64Encoder decoder = new BASE64Encoder();
return replaceEnter(decoder.encode(image));
}
}
</br>
注意:
1.使用frermarker标签时,尽量对数据做非空判断,避免出错
2.如果模板一开始样式不对,可以在后来在模板中修改好样式,重新另存为xml文件,然后到ftl文件中找到此内容,替换