工具:freemarker
有关freemarker的加载方式可参照
https://www.cnblogs.com/qiaoqiaodi/p/7082878.html
1、创建模板
网上有很多创建模板的文章可参考,大概可概括为以下几点
①建立word文档,根据自己的需求做好word内容的样式
②把word文档中,需要动态插入的内容替换为英文名称
③关键的一步,word文档另存为,保存格式为Word XML文档
④在另存为的xml文档中,把②中替换的英文名称替换为${xxx},作为模板参数
⑤更改xml文档后缀,改为.ftl,模板建立完成。
2、编辑参数
参数存放在map中,模板里所有的参数都要存在map中,map里的参数可以比模板参数多,但不能少
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("title", “ddddd”);
3、导出word(web端下载功能实现)
try {
// 获取模板
configuration.setClassForTemplateLoading(this.getClass(), 模板path);
Template wordTemplate = configuration.getTemplate(template);
// 文件名
String fileNameEncoded = URLEncoder.encode(fileName, "utf-8");
// 前端响应(HttpServletResponse)
response.setContentType("application/vnd.ms-word");
response.setHeader("Content-disposition", "attachment;filename=" + fileNameEncoded);
// 写入数据
Writer writer = response.getWriter();
wordTemplate.process(dataMap, writer);
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
}
4、图片的导出
网上有很多导出图片的方式,但都是导出到固定的参数,固定的位置。
现在,要实现在某个区域,既要导出文字,又要导出图片,而且图片是根据条件,
需要图片的时候就导出,不需要就不导出图片,实现图片的动态导出。
①实现这个功能,要先知道带图片word模板的结构,也就是xml结构
格式化xml模板后,可以找与图片相关的xml内容有以下几个地方
一、Relationships
<pkg:part pkg:name="/word/_rels/document.xml.rels"
pkg:contentType="application/vnd.openxmlformats-package.relationships+xml"
pkg:padding="256">
<pkg:xmlData>
<Relationships
xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId5"
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable"
Target="fontTable.xml" />
<Relationship Id="rId4"
Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"
Target="media/image1.jpeg" />
</Relationships>
</pkg:xmlData>
</pkg:part>
二、drawing,也就是图片所在word中的位置
<w:drawing>
<wp:inline distT="0" distB="0" distL="0" distR="0">
<wp:extent cx="5238750" cy="2944195" />
<wp:effectExtent l="19050" t="0" r="0" b="0" />
<wp:docPr id="1" name="图片 0" descr="t0121e99944f83e0638.jpg" />
<wp:cNvGraphicFramePr>
<a:graphicFrameLocks noChangeAspect="1"
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" />
</wp:cNvGraphicFramePr>
<a:graphic
xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData
uri="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:pic
xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture">
<pic:nvPicPr>
<pic:cNvPr id="0" name="t0121e99944f83e0638.jpg" />
<pic:cNvPicPr />
</pic:nvPicPr>
<pic:blipFill>
<a:blip r:embed="rId4" />
<a:stretch>
<a:fillRect />
</a:stretch>
</pic:blipFill>
<pic:spPr>
<a:xfrm>
<a:off x="0" y="0" />
<a:ext cx="5238750" cy="2944195" />
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst />
</a:prstGeom>
</pic:spPr>
</pic:pic>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
三、图片base64字节码存放的位置
<pkg:part pkg:name="/word/media/image1.jpeg" pkg:contentType="image/jpeg"
pkg:compression="store">
<pkg:binaryData>/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEP
................................
</pkg:binaryData>
</pkg:part>
根据以上三段内容,可以看出,一个图片在word中正常显示,离不开以上三段xml。所以,实现动态导出图片。就要在代码中手动编辑三段xml,作为参数放在模板中。
以上三段内容的关系如下:
drawing中【<a:blip r:embed="rId4" />】对应Relationships中的【<Relationship Id="rId4"】
Relationships中的【<Relationship Id="rId4"】的【Target="media/image1.jpeg" />】对应base64字节码的【<pkg:part pkg:name="/word/media/image1.jpeg"】
代码开发的时候,需要动态的改变【r:embed】、【Target】的值,一张图片对应一个值。
导出图片的时候,可能需要对图片进行压缩,可以参考https://www.cnblogs.com/miskis/p/5500822.html