项目中做到了一个动态生成word文档的需求,在这简单做下记录。
首先准备好要生成的world模板,设计好排版和内容,如下
将需要动态替换的内容用占位符代替,图片暂不处理,如下
然后将该word文档另存为Word 2003 XML 文档(*.xml),如下
然后用编辑器打开wordTemplate.xml,建议用现代编辑器如Sublime,方便对xml内容进行格式化,我是直接将其放入idea的springboot项目的resources目录下的template文件夹下进行编辑
可以看到原先word文档中的图片转为xml后变成了base64编码的字符串,如下
我们将base64字符串用占位符${picture}
替换,如下
然后我们检查其他占位符显示是否正常,如下面这种情况就是不正常的,需要将{}
中多余的东西删除
编辑完成后将wordTemplate.xml
改名为wordTemplate.ftl
。
模板有了,最后要做的就是生成word文档的代码实现,
首先需要在pom.xml文件中引入freemarker的依赖,如下
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
下面是详细的代码实现
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Encoder;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @Description: 根据ftl模板生成word文档工具类
* @Author along
* @Date 2019/6/21 13:32
*/
public class ExportDocUtil {
private final Logger logger = LoggerFactory.getLogger(getClass());
private Configuration configuration;
private String encoding;
private Map<String, Object> dataMap;
/**
* 构造函数
* @param dataMap 填充数据
* @param encoding 编码
* @param ftlPath ftl模板文件路径
*/
public ExportDocUtil(Map<String, Object> dataMap, String encoding, String ftlPath) {
this.dataMap = dataMap;
this.encoding = encoding;
configuration = new Configuration();
configuration.setDefaultEncoding(encoding);
configuration.setClassForTemplateLoading(this.getClass(), ftlPath);
}
private Template getTemplate(String ftlName) throws Exception {
return configuration.getTemplate(ftlName);
}
private static String getImageStr(String image) throws IOException {
InputStream is = new FileInputStream(image);
BASE64Encoder encoder = new BASE64Encoder();
byte[] data = new byte[is.available()];
is.read(data);
is.close();
return encoder.encode(data);
}
private static Map<String, Object> getDataMap() {
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("title", "world标题");
dataMap.put("name", "along");
dataMap.put("age", "12");
dataMap.put("address", "地球");
try {
dataMap.put("picture", getImageStr("D:\\图片1.png"));
} catch (IOException e) {
e.printStackTrace();
}
return dataMap;
}
/**
* 执行方法
* @param doc 生成word文件保存路径,包括文件名
* @param ftlName ftl模板文件名
* @return
* @throws Exception
*/
public boolean exportDoc(String doc, String ftlName) throws Exception {
Writer writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(doc), encoding));
getTemplate(ftlName).process(dataMap, writer);
logger.info("word创建完成>>>>>>>>>>");
return true;
} catch (Exception e) {
logger.error("", e);
}
if (writer != null) {
writer.flush();
writer.close();
}
return false;
}
// 测试
public static void main(String[] args) throws Exception {
ExportDocUtil maker = new ExportDocUtil(getDataMap(), "UTF-8", "/template");
String orderId = getDataMap().get("title").toString();
maker.exportDoc("D:\\" + orderId + ".doc", "wordTemplate.ftl");
}
}
执行main方法,在对应的D:\目录下找到world标题.doc
,打开内容如下
网友评论