前有java-poi替换模板文件word文档中的变量,生成Word文档,后有Java-Freemarker替换模板文件.ftl中的变量,生成Word文档。
Freemarker是如今最流行的文档处理组件,poi已经相对过时了。
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据,简单点就是替换模板中的变量, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
相关jar包、以及maven配置、或者gradle配置等等都可以去这个网站找到:mvn仓库。
1、根据需求创建word文档,下图是我想要的word,但是一些值是用了${变量名} 来代替。
2、把word另存为xml,不要直接修改尾缀,用word的另存为:
选择xml格式:
保存成xml之后,直接修改模板文件尾缀,把 xml 修改为 ftl 。然后便是检查变量名是否被word的一些标签隔离开了,如果${变量名}不是完整的,就要把那些多余的标签的删掉,并不会影响最后文档显示的格式,不然会报找不到对应的变量exception,如下图:
3、模板已经制作完毕,我把模板放在了 C:\image\freemarker.ftl 路径。然后便是java部分了:
package demo.freemarker_demo;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.Version;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author xch
* @description freemarker工具
* @date 2019-10-14
*/
public class FreemarkerDemo {
public static void test(String path){
Map dataMap = new HashMap<>();
try {
dataMap.put("name", "张三");
dataMap.put("idnumber", "411322199308302019");
dataMap.put("result1", "□");
dataMap.put("result2", (char)8730);// (char)8730 对号
dataMap.put("result3", "□");
dataMap.put("result4", "□");
dataMap.put("result5", "□");
dataMap.put("date", new SimpleDateFormat("yyyy年MM月dd日").format(new Date()));
dataMap.put("ipAddress", "110.0.0.1");
dataMap.put("confirmedBy", "xch");
dataMap.put("ipAddress", "110.0.0.1");
dataMap.put("datetime", new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss").format(new Date()));
Configuration configuration = new Configuration(new Version("2.3.0"));
configuration.setDefaultEncoding("utf-8");
//.ftl配置文件所在路径
//第一种使用相对一个java文件的相对路径
// configuration.setClassForTemplateLoading(new FreemarkerDemo().getClass(), "/doc/");
//第二种使用绝对路径
configuration.setDirectoryForTemplateLoading(new File("c:/image/"));
//第三种使用web项目的ServletContext路径
// configuration.setServletContextForTemplateLoading(null, "/doc/");
//以utf-8的编码读取ftl模板文件
Template template = configuration.getTemplate("freemarker.ftl", "utf-8");
//输出文档路径及名称
File outFile = new File(path);
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),
"utf-8"), 10240);
template.process(dataMap, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
String path = "C:\\image\\doc\\"+System.currentTimeMillis()+".doc";
test(path);
}
}
是不是很简单,关键代码只有两处,找到模板.ftl,然后用模板template的方法process(),把入参map和输出文件解析出来。map的key就是模板中的${变量值},匹配之后便是替换,然后便是生成最终的文档:
很简单的使用,这篇文章之所以写出来,是因为我的那一篇Java-POI替换Word模板文档中的变量,生成Word文档写的不甚明了,而且2019年了,还有很多在使用java-poi的,我没有否认poi的意思,我当年也是使用的它,完成我的第一个word模板的功能。
我只是想让更多的同行(xing)者,认识新的技术,新的技术可能更简单、更易用、更节省我们的time,省出的时间可以去捕获妹子啊什么的动物,毕竟妹子对于程序员来说,是数码宝贝一般的稀有动物。哈哈,不侃了。
注意三点,我使用时遇到的注意点:
1:上面的红字,在由word转到ftl的过程中,一定要核对${变量名} 是否被一些标签拆分开了,那么便会报解析异常:
freemarker.core.ParseException: Syntax error in template "freemarker.ftl"
2:我如果最终导出的word文件尾缀.doc,改为.docx,程序无异常,但是最终的文件就是报:无法打开......:
3:(char)8730 是java中的对勾/对号,别看这个对号,我再网上找了好久。
4:-----------------------------------------------------------------------------------------不关注我“象话”吗?(哈哈,逗比)
适应手机端的文件模板生成,我后续会补上......