公司前一段时间做的一个项目中应用到了这个技术,需要后台获取数据后在前台直接下载word文档,利用freemarker模版生成的doc文档在电脑上可以正常打开,但是发送到手机上打开则全部变成“乱码”。但实际上并不是乱码,而是xml格式的代码,在手机等移动端显示不出正常的文档信息。之后辗转查询使用了很多方案,比如利用poi操作,利用jacob进行格式转换,但是效果都不尽如人意,而且处理过程非常复杂,浪费了大量时间。最终,通过不断摸索,找到了非常完美的解决方案。不需要先生成xml格式的doc文档再去转换,而是戒指在后台利用模版添加数据后,利用IO流进行替换,可以直接生成标准的docx文档。
首先需要理解的一点是,docx文档本身是一个压缩文件。在利用这个方案前要先准备好docx模版。在这个docx模版中,将要替换的数据用${}的方式替换掉,先占好位置。如图:
将docx改后缀名为.zip并解压出来。在word文件夹下有一个文件为、:document.xml
利用notpad等工具打开此文件,将格式修改好,比如在xml文件中${xxx}分别氛围${ , xxx 以及 } 三部分存贮在不同的标签下,要将他们合并到一起。
随后将保存好的document.xml和之前定义好的zip文件放入工程的配置文件夹下,方便引用。
核心代码如下
Configuration
configuration = new Configuration();
/** 设置编码 **/
/** 我的ftl文件是放在D盘的**/
String fileDirectory = "D:/cache/qqChace/T1/xlsx";
/** 加载文件 **/
configuration.setDirectoryForTemplateLoading(new File(fileDirectory));
/** 加载模板 **/
Template template = configuration.getTemplate("document.xml");
/** 准备数据 **/
Map<String,String> dataMap = new HashMap<>();
/** 在ftl文件中有${textDeal}这个标签**/
dataMap.put("id","哈士奇");
dataMap.put("number","20");
dataMap.put("language","java,php,python,c