首先使用word文档写好使用的模板,然后另存为xml格式,然后对xml对想要动态生成的进行编辑(在看别人的问文档的时候说直接在word模板中把动态生成的内容用类似${user_name}的字段替换,user_name就是我们在程序中设置的动态变量,但是可能因为word版本的问题最动态的${user_name}生成不了,它${}变成了wordxml格式中其他标签了,只把动态user_name生成了,所以我们直接、编辑xml文档就行),在需要替换的动态文字的部分替换成类似${title_name}的字段,在后续程序中使用,修改完毕以后把后缀给成ftl格式即可
以下代码来自于网络,但是有些瑕疵:
我已经更改了,原来的代码可能执行的时候找不到ftl模板文件。把ftl模板文件放在resource目录下即可,如果需要放在resource目录的其他目录下需要更配一个配置设置即可
//加载模板(路径)数据 config.setClassForTemplateLoading(this.getClass(), "/");
原来直接写不是"/"而是“”,自己找了好半天。这样写肯定没有问题,但是还有可能出现读不到模板这个问题,这个可能和你生成的模板有关系,多试几次可能就好了。
还有一个要注意的问题就是替换图片。需要现在word中插入一张图片,在xml中会有对应图片的base64码,到时候需要把这个base64删除干净替换成${imgheader},一定要删除干净,不然动态替换生成的图片会显示花了。
package com.example.worddemo.freemarker;
import freemarker.core.ParseException;
import freemarker.log.Logger;
import freemarker.template.*;
import sun.misc.BASE64Encoder;
import java.io.*;
import java.util.Map;
/**
* Create by Mrli on 2020/7/28
*/
public class ExportMyWord {
private Logger log = Logger.getLogger(ExportMyWord.class.toString());
private Configuration config = null;
public ExportMyWord() {
config = new Configuration(Configuration.VERSION_2_3_28);
config.setDefaultEncoding("utf-8");
//config.setClassForTemplateLoading(this.getClass(),"/");
}
/**
* FreeMarker生成Word
* @param dataMap 数据
* @param templateName 目标名
* @param saveFilePath 保存文件路径的全路径名(路径+文件名)
* @Author Huang Xiaocong 2018年12月15日 下午10:19:03
*/
public void createWord(Map dataMap, String templateName, String saveFilePath) {
//加载模板(路径)数据
config.setClassForTemplateLoading(this.getClass(), "/");
//设置异常处理器 这样的话 即使没有属性也不会出错 如:${list.name}...不会报错
config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
Template template = null;
if(templateName.endsWith(".ftl")) {
templateName = templateName.substring(0, templateName.indexOf(".ftl"));
}
try {
template = config.getTemplate(templateName + ".ftl");
} catch (TemplateNotFoundException e) {
log.error("模板文件未找到", e);
e.printStackTrace();
} catch (MalformedTemplateNameException e) {
log.error("模板类型不正确", e);
e.printStackTrace();
} catch (ParseException e) {
log.error("解析模板出错,请检查模板格式", e);
e.printStackTrace();
} catch (IOException e) {
log.error("IO读取失败", e);
e.printStackTrace();
}
File outFile = new File(saveFilePath);
if(!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
Writer out = null;
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outFile);
} catch (FileNotFoundException e) {
log.error("输出文件时未找到文件", e);
e.printStackTrace();
}
out = new BufferedWriter(new OutputStreamWriter(fos));
//将模板中的预先的代码替换为数据
try {
template.process(dataMap, out);
} catch (TemplateException e) {
log.error("填充模板时异常", e);
e.printStackTrace();
} catch (IOException e) {
log.error("IO读取时异常", e);
e.printStackTrace();
}
log.info("由模板文件:" + templateName + ".ftl" + " 生成文件 :" + saveFilePath + " 成功!!");
try {
out.close();//web项目不可关闭
} catch (IOException e) {
log.error("关闭Write对象出错", e);
e.printStackTrace();
}
}
/**
* 获得图片的Base64编码
* @param imgFile
* @return
* @Author Huang Xiaocong 2018年12月15日 下午10:15:10
*/
public String getImageStr(String imgFile) {
InputStream in = null;
byte[] data = null;
try {
in = new FileInputStream(imgFile);
} catch (FileNotFoundException e) {
log.error("加载图片未找到", e);
e.printStackTrace();
}
try {
data = new byte[in.available()];
//注:FileInputStream.available()方法可以从输入流中阻断由下一个方法调用这个输入流中读取的剩余字节数
in.read(data);
in.close();
} catch (IOException e) {
log.error("IO操作图片错误", e);
e.printStackTrace();
}
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
}
package com.example.worddemo.freemarker;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* Create by Mrli on 2020/7/28
*/
public class FreemarkerDemo {
@Test
public void test1(){
ExportMyWord emw = new ExportMyWord();
Map dataMap = new HashMap();
dataMap.put("name", "黄xx");
dataMap.put("age", 26);
dataMap.put("blog", "sun_flower火柴客");
dataMap.put("email", "[email protected]");
dataMap.put("gender", "男");
dataMap.put("imgheader", emw.getImageStr("C:/Users/jtkj/Downloads/590x470.jpg"));
dataMap.put("telephone", "123456789101");
dataMap.put("address", "深圳");
dataMap.put("naturework", "全职");
dataMap.put("industry", "IT");
dataMap.put("aplication", "Java开发");
dataMap.put("time", "2013年-2017年");
dataMap.put("schoolname", "南昌大学");
dataMap.put("education", "本科");
dataMap.put("projectname", "电子证照xxxx");
dataMap.put("projecttime", "2017年3月");
dataMap.put("projectcontent", "我们除了有视、听、味、嗅、触这些外感系统之外,人类还有一个非常重要的内感系统,就是我们情绪和情感的世界。"
+ "这种感受是那样地细腻、微妙、强烈、深沉;看不见、摸不着,说不清、道不明。...");
emw.createWord(dataMap, "test3.ftl", "C:/Users/jtkj/简历.doc");
}
}
完全照抄,参考https://www.cnblogs.com/sun-flower1314/p/10126111.html