**本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接 **
首先需要注意的是,使用freemaker生成的文档,其本质仍然为xml文档。
使用freemaker生成word文档主要实现步骤如下:
添加依赖(第1步) -> 制作模板(第2,3,4,5,6步) -> 程序编写(第7,8,9,10步)
详细步骤:
-
下载导入freemaker-xx.jar包,或者 maven:pom.xml中添加freemaker依赖
-
修改已有的"文档.doc":将填充内容修改为 {{paranames}}
-
文档另存为“xxx_template.xml”,建议复制备份一份“xxx_template-副本.xml”
-
使用文本编辑器,notepad++/sublineText等打开xml文件,使用插件美化xml(notepadd++美化路径为:插件->XML Tools -> Pretty print),将其中的{{parames}}替换为 "${paranames}",有些“{{”, "}}" 分开了记得合并或删除
-
对于需要list, 格式为
<#list listitems as item> ...${item.para1} ... ${item.para2}... </#list>
-
另存为"xxx_template.ftl"
-
项目中建立模板文件路径包:....template.package, 你喜欢的包名都可以
-
包中建立MDoc.java类:内容如下:
/*** * MDoc类,根据模板与数据生成文件 */ package com.xxxxx.export.doc.template; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.io.Writer; import java.util.Map; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; public class MDoc { private Configuration configuration = null; public MDoc() { configuration = new Configuration(Configuration.getVersion()); configuration.setDefaultEncoding("utf-8"); } /** * * @param dataMap 要填入模板的数据 * @param fileName 生成文档的路径 * @param template 模板文件的名称,如"xxx.ftl" * @throws UnsupportedEncodingException */ public void createDoc(Map<String, Object> dataMap, String fileName, String template) throws UnsupportedEncodingException { // dataMap 要填入模本的数据文件 // 这里我们的模板是放在与本类同一个包路径下 configuration.setClassForTemplateLoading(MDoc.class, "/" + MDoc.class.getPackage().getName().replace(".", "/")); Template t = null; try { t = configuration.getTemplate(template); } catch (IOException e) { e.printStackTrace(); } // 输出文档路径及名称 File outFile = new File(fileName); Writer out = null; FileOutputStream fos = null; try { fos = new FileOutputStream(outFile); OutputStreamWriter oWriter = new OutputStreamWriter(fos, "UTF-8"); // 这个地方对流的编码不可或缺,使用main()单独调用时,应该可以,但是如果是web请求导出时导出后word文档就会打不开,并且包XML文件错误。主要是编码格式不正确,无法解析。 out = new BufferedWriter(oWriter); } catch (FileNotFoundException e1) { e1.printStackTrace(); } try { t.process(dataMap, out); out.close(); fos.close(); } catch (TemplateException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
-
将 “xxx_template.ftl” 拷贝至同一包路径下。
-
调用方法关键代码如下:
String filepath = "D://..../filename.doc";
MDoc mdoc = new MDoc();
try {
mdoc.createDoc(dataMap, filepath, "xxx_template.ftl");
} catch (UnsupportedEncodingException e) {
LogKit.error("导出word错误:e = " + e.getMessage());
}
File outputfile = new File(filepath);
....
一些可能需要的其他需求实现方式:
-
插入图片:
需要将图片链接转换为base64格式,并放置到到模板中。
<!-- ${pic_index}表示取元素在列表中的下标index --> ... <!-- 资源索引 --> <#list picUrls as picUrl> <Relationship Id="rId${picUrl_index}Png" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image${memUrl_index}.png"/> </#list> ... <!-- base64资源 --> <#list picUrls as picUrl> <pkg:part pkg:name="/word/media/image${picUrl_index}.png" pkg:contentType="image/png" pkg:compression="store"> <pkg:binaryData>${picUrl.imageBase64!''}</pkg:binaryData> </pkg:part> </#list> ... <!-- 引用,仅放置关键处代码,具体需要使用模板来制作 --> <a:blip r:embed="rId${picUrl_index}Png" cstate="print"> ...
-
换行:
paraHaveLineBreak.replaceAll("/n", "<w:br/>")