1.制作freemarker模板文件
制作freemarker模板文件可经过这几个步骤演变:
.doc文件 –> .xml文件 –> *.ftl文件
①.使用office软件新建一个word文件,设计好文件的格式,需要用数据来填充的地方可以使用一个变量名来占位(这里先不要freemarker标签,就使用普通的英文单词占位即可),保存。如图:
②.将上一步的word文件另存为xml格式的文件,如图:
③.使用任意一个文本编辑器打开该xml文件(由于该xml文件内容比较复杂,建议使用Hbuilder这种前端页面编辑器软件打开,因为可以美化文件内容布局,这样看起来就比较有层次),可以看到,我在第一步中设置的几个变量在xml文件里体现如下:
而对于插入的图片来说,已经被office软件转换成base64格式的字符串保存在 包裹的地方,如图:
2.使用freemarker标签替换掉需要填充的数据模型
基于上一步,接下来需要使用freemarker标签替换调用需要填充的内容,如图:
而对于图片,则需要将生成的base64格式的字符串给删掉,然后替换成任意一个你想设置的字符变量,如图:
3.使用Java代码完成word文件的生成(具体代码请下载代码查看)
1>.添加jar支持
2>.设置模板的路径
public FreemarkerUtils(String encoding) {
this.encoding = encoding;
config = new Configuration(Configuration.VERSION_2_3_23);
config.setDefaultEncoding(encoding);
config.setClassForTemplateLoading(this.getClass(), "/");
}
3>.根据模板路径读取freemarker模板到JVM:
private Template getTemplate(String templatePath) {
Template template = null;
try {
template = config.getTemplate(templatePath);
} catch (TemplateNotFoundException e) {
e.printStackTrace();
throw new RuntimeException("找不到doc模板文件." + e.getMessage());
} catch (MalformedTemplateNameException e) {
e.printStackTrace();
throw new RuntimeException("doc模板文件格式不正确." + e.getMessage());
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("doc模板文件解析出错." + e.getMessage());
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("doc模板文件流读取出错." + e.getMessage());
}
return template;
}
4>.使用数据模型填充模板
public void generateFile(String templatePath, String targetPath, Map<String, Object> dataModel) {
Writer writer = null;
Template template = null;
try {
if (FileUtils.createFile(targetPath)) {// 新建doc文件
template = getTemplate(templatePath);// 拿模板
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(targetPath), encoding));
// 合成
template.process(dataModel, writer);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("生成目标文件出错." + e.getMessage());
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("关闭流失败." + e.getMessage());
}
}
}
注:在使用freemarker生成word文件的过程中,需要注意:
1. 若文件中有图片需要插入,则在制作freemarker模板的过程中,图片的内容需要被<pkg:binaryData> </pkg:binaryData>
标签包含,否则无法插入图片;
2. 对应的,在用Java代码插入图片时,需要将图片转为base64格式的字符串;转换代码如图:
public static String getImageStr(String imgFilePath) {
InputStream in = null;
byte[] data = null;
StringBuilder sb = new StringBuilder();
try {
in = new FileInputStream(imgFilePath);
data = new byte[in.available()];
in.read(data);
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
sb.append(encoder.encode(data));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return sb.toString();
}