如何使用freemaker生成word文档| Java Debug 笔记
**本文正在参加「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”:将填充内容修改为
文档另存为“xxx_template.xml”,建议复制备份一份“xxx_template-副本.xml”
使用文本编辑器,notepad++/sublineText等打开xml文件,使用插件美化xml(notepadd++美化路径为:插件->XML Tools -> Pretty print),将其中的
{{parames}}
替换为${paranames}
,有些{{`, `}}
分开了记得合并或删除对于需要list, 格式为
1
<#list listitems as item> ...${item.para1} ... ${item.para2}... </#list>
另存为”xxx_template.ftl”
项目中建立模板文件路径包:….template.package, 你喜欢的包名都可以
包中建立MDoc.java类:内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68/***
* 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” 拷贝至同一包路径下。
调用方法关键代码如下:
1 | String filepath = "D://..../filename.doc"; |
一些其他需求:
插入图片:
需要将图片链接转换为base64格式,并放置到到模板中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<!-- ${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">
...换行:
1
paraHaveLineBreak.replaceAll("/n", "<w:br/>")