简介
FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。模板编写为FreeMarker Template Language (FTL)
主要步骤:
- 创建word文档,先把一个基本模板做好,模板中使用连续的数字或者英文填充(搜索时,不会间断,方便替换)。
- 将该 word 另存为 .xml 的格式,搜索需要填充的数据用占位符${变量名}替换。
- 将.xml改成.ftl ,调用相关接口生成文件(主要是方便编辑器识别,可不改)
一、创建模板
word源文件
另存为xml格式文件
<w:tbl> 表示一个表格 、<w: tr> 表示一行、<w: tc>表示一列
学习了html,比较容易看出来
二、生成文档
1、工具类
package freemarkerStudy;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler;
import java.io.File;
import java.io.FileWriter;
import java.util.Map;
public class generateHtmlDocument {
/**
* @param TemplatePath 模版存放目录
* @param TemplateName 模版名
* @param root 填充的数据
* @param GenerateFilename 生成文件名
* @throws Exception
*/
public static void generate(String TemplatePath, String TemplateName, Map<String, Object> root, String GenerateFilename) throws Exception {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_32);
//指定模板文件的来源目录
cfg.setDirectoryForTemplateLoading(new File(TemplatePath));
cfg.setDefaultEncoding("UTF-8");
//设置错误的显示方式(日志)
//在生产系统中:TemplateExceptionHandler.RETHROW_HANDLER 默认值
//在开发HTML模板期间:TemplateExceptionHandler.HTML_DEBUG_HANDLER
//在开发非HTML模板期间:TemplateExceptionHandler.DEBUG_HANDLER
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
//获取模板文件
Template temp = cfg.getTemplate(TemplateName);
//合并模板和数据模型
File file = new File(TemplatePath + "new-built");
//如果文件夹不存在,则创建文件夹
if (!file.exists()) {
//file.mkdirs();//多级目录
file.mkdir();//只创建一级目录
}
//Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(TemplatePath + "new-built/" + GenerateFilename)));//输出文件
FileWriter out = new FileWriter(TemplatePath + "new-built/" + GenerateFilename);
//Writer out = new OutputStreamWriter(System.out);//输出控制台
//StringWriter out = new StringWriter();//输出为字符串,可作为接口动态返回
temp.process(root, out);
out.flush();//可不手动调用
}
}
2、测试类
package freemarkerStudy;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class generateHtmlDocument {
public static void main(String[] args) throws Exception {
String TemplatePath = "D:\\学习\\Java_Study\\results\\templates\\";
//String TemplateName = "html模版.ftl";
String TemplateName = "word模版.xml";
Map<String, Object> root = new HashMap<>();
root.put("title", "期末成绩表");
ArrayList<Map> list = new ArrayList<>();
Map<String, String> map = new HashMap<>();
map.put("lastname", "张三");
map.put("subject", "语文");
map.put("achievement", "98");
list.add(map);
Map<String, String> map2 = new HashMap<>();
map2.put("lastname", "李四");
map2.put("subject", "属性");
map2.put("achievement", "97");
list.add(map2);
root.put("achievementList", list);
//generate(TemplatePath, TemplateName, root, "shengcheng.html");
generate(TemplatePath, TemplateName, root, "shengcheng.doc");
}
}
注意:生成的word要为doc格式,否则打不开
3、生成的文件
Word
Html
三、 其他杂项
1、MVC模式
FreeMarker最初的设计,是被用来在MVC模式的Web开发框架中生成HTML页面的,它没有被绑定到 Servlet或HTML或任意Web相关的东西上。但它也可以用于非Web应用环境中,在这里你可以改造一下生成文件类,以字符串的格式返回,他就变成了 MVC (模型 视图 控制器) 模式。
2、模版磁盘空间占用
这里使用了IDEA格式化,改造模版之后,会有许多换行符,当然这里磁盘空间会大几kb,可忽略,但我已经写了就赋上来吧
代码
package freemarkerStudy;
import java.io.*;
public class generateHtmlDocument {
/**
* @param inputFile
* @param outputFile
* @throws IOException
* 去除换行符,读到内存中,小文件
*/
public static void removeNewLines(File inputFile, File outputFile) throws IOException {
String content = readFileToString(inputFile);
content = content.replaceAll("\\r|\\n", "");
writeStringToFile(content, outputFile);
}
//处理大文件转化
public static void removeNewLinesBig(File inputFile, File outputFile) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(inputFile));
BufferedWriter writer = new BufferedWriter(new FileWriter(outputFile))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.replaceAll("\\r|\\n", "");
writer.write(line);
}
}
}
private static String readFileToString(File file) throws IOException {
try (BufferedReader reader = new BufferedReader(new FileReader(file))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
}
private static void writeStringToFile(String content, File file) throws IOException {
try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
writer.write(content);
}
}
}