Java通过freemarker方式导出word文档的优缺点都很明显。
优点:操作简单,方便,word的模板的格式样式都被保留了下来。
缺点:需要有固定或者有规律的模板,如果要导出的表格当中不确定哪里是合并单元格用这种方法是实现不了的。
下边是实现过程:
1.准备模板,在模板的需要我们导出数据的地方写上东西占位(最好是英文单词并且写好之后word不会报红色波浪线,不然后边会有点麻烦);注意:不能用相同的单词占位,请忽略的我截图中的hour1和min1,操作失误,大家自行改成不同的单词吧。
2.准备好模板之后,将模板另存为xml文件,注意是点击文档左上角的保存然后另存为,不是手动修改后缀!!
3.用文本编辑工具打开保、另存好的xml文件,并用查找下一项找到我们在文档中填写的英文单词,将单词放到
里边。
4.如果我们需要将这一页或者这个表在同一个文档重复出现的话,就需要给这一页或者这一个表格加一个循环。例如我要生成多个故障登记表在同一个文档中,那么我们需要在需要循环的地方加上<#list listname as listitem>,在循环结束的地方加上</#list>,这是循环体的标签。因为我要循环这一页,而一个文档只有这一页,所有我是这么加的<w:body><#list listname as listitem>···中间省略一万字···</#list></w:body>。循环体将一整页都包含了起来。并且对应的我们文档中填写的英文单词要变为${listitem.单词}
5.xml文件修改了之后,直接手动改后缀名为ftl,就可以作为模板使用了。
6.具体的使用方法。
import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Fault_explord {
/**
path----输出路径(带文件名)
listfault---测试用的数据,将数据库数据查出来放到list里了,可以忽略!
*/
public static void exportSimpleWord(String path, List<DmFaultTask> listfault) throws Exception{
// 要填充的数据, 注意map的key要和word中${xxx}的xxx一致
List<Map<String, String>> rsult = new ArrayList<>();
for (int i = 0; i < listfault.size(); i++) {
Map<String, String> dataMap = new HashMap<>();
dataMap.put("year", "2020");
dataMap.put("month","01");
dataMap.put("day", "01");
dataMap.put("year1", "2020");
dataMap.put("month1","05");
dataMap.put("day1", "02");
dataMap.put("hour","1");
dataMap.put("min", "1");
dataMap.put("hour","2");
dataMap.put("min", "2");
dataMap.put("reason","hahaha~~~" );
dataMap.put("method","heiheihei~~~" );
dataMap.put("name","饮血剑" );
dataMap.put("version","10.9.2" );
dataMap.put("number","000001" );
dataMap.put("number1","000002" );
dataMap.put("in","阿富汗" );
dataMap.put("go","新加坡" );
//注意:每一个用单词占过位置的格都要赋值!不然报错。
rsult.add(dataMap);
}
Map<String,Object> dataMap1 = new HashMap<String,Object>();
dataMap1.put("recordList",rsult);
//Configuration用于读取ftl文件
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
/*以下是两种指定ftl文件所在目录路径的方式, 注意这两种方式都是
* 指定ftl文件所在目录的路径,而不是ftl文件的路径
*/
//指定路径的第一种方式(根据某个类的相对路径指定)
configuration.setClassForTemplateLoading(Plan_explord.class, "/tem/");
//指定路径的第二种方式,我的路径是C:/a.ftl
//configuration.setDirectoryForTemplateLoading(new file(C:/));
// 输出文档路径及名称
File outFile = new File(path);
//以utf-8的编码读取ftl文件
Template t = configuration.getTemplate("aaa.ftl","utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"),10240);
t.process(dataMap1, out);
out.close();
}
}