公司关于自动化测试的项目,需要对测试项以及data结果数据文件生成报表。老旧项目单纯使用poi,写了很多代码,大致就是需要创建表格,传入数据控制poi生成word段落对象文档的一套流程。需要整改,就查看相关报表生成的东西,发现大家都比较推荐freemaker,个人觉得优点在于减少代码量,不需要在代码上去控制报表样式啊。复杂的报表,如果去控制段落对象,替换标题等等是很麻烦的。freemaker就是先去word画出自己想要的模板,这样减少代码工作量。然后只要代码去动态传值进去就好(替换值)。废话不多说,具体概念百度百科有。下面是写的一个demo。仅供参考(本demo是doc类型模板,这个doc和docx是不一样的哈,好像是因为读取不一样,一个是二进制读取,反正就是看到这么一个文章。避免踩坑)
一、用word画自己想要的报表样式:这里是我的:
保存文件xml格式。(用的是Microsoft Office Word,保存类型一定选这个哈,好像别的是不兼容还是什么的,反正避免没必要的麻烦,选这个错不了,wps没有这个类型,所以用不了)
二、需要一个xml格式化工具将这个文件格式换一下,方便阅读和修改。编辑器(推荐Firstobject free XML editor)或者使用sublime(更推荐,就是需要安装,我用的这个)sublime使用方法:打开xml代码,修改关键位置的数据,这时候需要有格式化代码的工具,才能看到规整的代码,推荐使用sublime的格式化工具,需要安装,参照sublime格式化。选择selection->format->indent XML,就可以一键格式化当前XML文件。
将我们需要动态导入的数据用${}替换,比如我的杂波频率的数值我用的我data文件的xb30kFreq和xb60kFreq的变量。那我这里就这样替换
在文档内容中需要动态修改内容的地方,换成freemaker的标识,其实就是Map<String,Object>中的key,在加入图片占位的地方,会看到一片base64编码后的代码,把base64替换成
i
m
a
g
e
,
也
就
是
M
a
p
<
S
t
r
i
n
g
,
o
b
j
e
c
t
>
中
的
K
e
y
,
值
必
须
要
处
理
成
b
a
s
e
64
;
代
码
如
:
<
w
:
b
i
n
D
a
t
a
w
:
n
a
m
e
=
“
w
o
r
d
m
l
:
/
/
自
定
义
.
p
n
g
"
x
m
l
:
s
p
a
c
e
=
"
p
r
e
s
e
r
v
e
"
>
{image},也就是Map<String,object>中的Key,值必须要处理成base64;代码如:<w:binData w:name=“wordml://自定义.png" xml:space="preserve">
image,也就是Map<String,object>中的Key,值必须要处理成base64;代码如:<w:binDataw:name=“wordml://自定义.png"xml:space="preserve">{image}</w:binData>
注意:“>${image}<”这尖括号中间不能加任何其他的诸如空格,tab,换行等符号。
如果需要循环,则使用:<#list maps as map></#list> maps是Map<String, Object>中key,值为数组,map为自定义;
三、到这,我们的模板就算完成了。但是很重还要的一步,在保存的时候需要将后缀改成.ftl格式,并且改完不要用word去打开它。如图:
四、代码部分``
package com.ss.poi.LiuTest;
import com.google.gson.JsonElement;
import com.ss.poi.entity.TestResultData;
import com.ss.poi.util.DoubleUtil;
import com.ss.poi.util.GsonUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class Utils {
private Configuration configuration = null;
public Utils(){
configuration = new Configuration();
configuration.setDefaultEncoding("UTF-8");
}
public static void main(String[] args) throws IOException, TemplateException {
Utils utils = new Utils();
utils.createWord();
}
/**
* 初始化配置文件
* @return Configuration
*/
public void createWord() throws TemplateException, IOException {
//data数据文件地址
String filepath = "D:/L/LiuWeiSS7/频谱电源杂波20200314-151457.data";
//自己的一个工具类,data文件为json格式。这里读进来后转换为String
String dataStr = GsonUtil.readFile2String(filepath);
//自己的工具类转数据体用
TestResultData data = GsonUtil.jsonToObject(dataStr, TestResultData.class);
//真正的部分从这里开始
Map<String, Object> dataMap = new HashMap<String, Object>();
String dataIndex = data.getDataIndex();
double xb30kFreq = data.getTestExportData().get("xb30kFreq").getAsDouble();
double xb60kFreq = data.getTestExportData().get("xb60kFreq").getAsDouble();
double dyzbMax = data.getTestInputData().get("dyzbMax").getAsDouble();
double dyzbMax2 = data.getTestInputData().get("dyzbMax").getAsDouble();
double xb30kLevel = data.getTestExportData().get("xb30kLevel").getAsDouble();
double xb60kLevel = data.getTestExportData().get("xb60kLevel").getAsDouble();
dataMap.put("dataIndex", dataIndex);
dataMap.put("xb30kFreq", xb30kFreq);
dataMap.put("xb60kFreq", xb60kFreq);
dataMap.put("dyzbMax", dyzbMax);
dataMap.put("dyzbMax2", dyzbMax2);
dataMap.put("xb30kLevel", xb30kLevel);
dataMap.put("xb60kLevel", xb60kLevel);
//.ftl模板路径
configuration.setDirectoryForTemplateLoading(new File("D:\\L"));
//文件名称
Template t = configuration.getTemplate("20200314-151457.ftl");
try {
//输出路径
File outFile = new File("D:/outFile" + new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date()) + ".doc");
Writer out = null;
out = new BufferedWriter(new OutputStreamWriter((new FileOutputStream(outFile)), "UTF-8"));
t.process(dataMap, out);
System.out.println("成功生成");
} catch (IOException e) {
e.printStackTrace();
}
}
}
这里是一个小的应用,看到相关资料还可以做一些报表图形的生成。总之需要根据自己的应用场景去选择。