Java中利用freemarker模板动态生成word含表格
·
最近公司有导出word的需求,由于word的样式有的很复杂所以记录一下Java中利用freemarker模板动态生成word含表格,以防以后忘记。
1、word表格的模板
删掉无用的数据留下基础的样式
(如果有需要循环的list表格的位置只留表头和第一行数据)

把调整完的word另存为xml格式:

将保存的xml文件后缀改成.ftl

格式化一下xml,可以去百度一下在线格式化xml那里格式化,格式化完看着清晰一些,要不然容易误删标签导致文件打不开
2、Java代码
配置
项目的gradle文件,xxx.gradle文件里配置好拷贝ftl文件的代码
(绿色部分是需要添加的代码,gradle版本不一样文件路径也不同,下图是4.0版本路径)
2.4版本 into "${buildDir}/classes/main"
4.0版本 into "${buildDir}/classes/java/main"

1、需要导入freemarker的包
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.20</version>
</dependency>
2、代码编写
service层
假装这里有代码,就是查出你要展示到word里面的数据
controller层
@ResponseBody
@RequestMapping("/getWord.ajax")
public Map<String, Object> getWord(HttpServletResponse response, Long roundId) {
response.setContentType("application/x-www-form-urlencoded");
response.setHeader("Content-disposition", "attachment; filename=vote1.doc");
Map<String, Object> resultMap = new HashMap<>();
ResultDO<TurnVoteResult> turnVoteResultDO = electionService.getVoteResultList(roundId);
if (turnVoteResultDO.success()) {
TurnVoteResult turnVoteResult = turnVoteResultDO.getObj();
File file = new FreemarkerUtil().createVoteElected(turnVoteResult);
try (
ServletOutputStream outputStream = response.getOutputStream();
InputStream input = new FileInputStream(file);
) {
byte[] bytes = new byte[input.available()];
int read = input.read(bytes);
if (read > 0) {
outputStream.write(bytes);
outputStream.flush();
}
} catch (IOException e) {
VoteLogger.error(e);
}
super.setSuccess(resultMap);
} else {
super.setServiceFailure(resultMap, turnVoteResultDO);
}
return resultMap;
}
createVoteElected方法的代码(voteElected.ftl是文件名字 放在跟这个方法同一文件夹下就行)
public File createVoteElected(TurnVoteResult turnVoteResult) {
Map<String, Object> dataMap = new HashMap<>();
//File outFile = new File("E:\\voteElected.doc"); // 生成文件路径,测试的时候可以用这句话把文件下载到本地
File outFile = new File("voteElected.doc"); // 生成文件的路径
dataMap.put("turnVoteResult", turnVoteResult);
try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), StandardCharsets.UTF_8))) {
configuration.setClassForTemplateLoading(this.getClass(), "");
Template t = configuration.getTemplate("voteElected.ftl", "UTF-8"); // 文件名,并且设置编码
if (t != null) {
t.process(dataMap, out);
}
out.flush();
} catch (IOException | TemplateException e1) {
VoteLogger.error(e1);
}
return outFile;
}
3.循环导出
现在替换ftl文件里的值,换成变量 格式是下面这样turnVoteResult是传入的实体名字,meetingPrintName是实体里字段的名字
${(turnVoteResult.meetingPrintName!'')?html}

如果word里有需要循环的地方,在ftl文件里要循环的列上加上
<#list turnVoteResult.turnCandidateVoList as candidate>

注意别忘记结束标签

如果循环里面还需要if判断的话看下图

1、判断对象不为空
如果name为null,freemarker就会报错。
如果需要判断对象不为空:
<#if name??>
……
</#if>
当对象有属性时,对象及对象属性都有可能为空,可写成:
<#if (user.name)??>//判断对象属性不为空
……
</#if>
判断String等值
<#if (qrCodeInfo.noteCountFlag)! =='Y'>
XXXX
<#else>
XXXX
</#if>
2、判断List是不为空
<#if userList?? && (userList?size > 0) >
<h1>List不为空</h1>
<#list userList as uInfo>
……
<#else>
<h1>显示</h1>
</#if>
ftl文件编写完成就可以测试一下啦!
更多推荐

所有评论(0)