最近要使用导出文档,网上找了资料,现在自己的总结如下
一、文档模板的设置
1. 选定表格中要替换的文本,然后键盘使用 Ctrl + F9 组合键将其设置为域,接着鼠标右键选择【编辑域(E)...】:
2. 在弹出的对话框中,类别选择“邮件合并”,域名选择 "MergeField",域属性中的域名填入模版表达式${year},点击【确定】按钮;
3. 重复步骤2,替换表格中的其他文本内容:
二、 代码引入依赖
pom.xml
org.springframework.boot spring-boot-starter-freemarkerorg.apache.poi poi4.1.1 org.apache.poi poi-ooxml4.1.1 org.jxls jxls2.6.0 ch.qos.logback logback-coreorg.jxls jxls-poi1.2.0 fr.opensagres.xdocreport fr.opensagres.xdocreport.core2.0.2 fr.opensagres.xdocreport fr.opensagres.xdocreport.document2.0.2 fr.opensagres.xdocreport fr.opensagres.xdocreport.template2.0.2 fr.opensagres.xdocreport fr.opensagres.xdocreport.document.docx2.0.2 fr.opensagres.xdocreport fr.opensagres.xdocreport.template.freemarker2.0.2 commons-io commons-io2.5
controller方法
@RequestMapping("/exportWord")
public void exportWord(HttpServletResponse response,TpfWholeEntity tpfWholeEntity){
ExportWordUtil ewUtil = new ExportWordUtil();
Map dataMap = tpfWholeService.getShowMap(tpfWholeEntity);
//按月获取单个企业的能耗量
List energyList = tpfWholeService.findEnergysMonth(tpfWholeEntity);
dataMap.put("energyList", energyList);
//按月获取单个企业的碳排放量
List tpfMonthList = tpfWholeService.findTPFMonth(tpfWholeEntity);
dataMap.put("tpfMonthList", tpfMonthList);
ewUtil.exportWord(dataMap, "tpfWhole.ftl", response, "1111.doc");
}
其中showMap方法大致没用就是创建一个HashMap,然后设置属性,然后返回这个map,大致截图如下
导出的exutil代码
package com.cshl.modules.reports.utils;
import freemarker.template.*;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Map;
import static freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS;
@Slf4j
public class ExportWordUtil {
private Configuration config;
public ExportWordUtil() {
config = new Configuration(DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
config.setDefaultEncoding("utf-8");
}
public void exportWord(Map dataMap, String templateName, HttpServletResponse response, String fileName) {
//加载模板(路径)数据,也可使用setServletContextForTemplateLoading()方法放入到web文件夹下
config.setClassForTemplateLoading(this.getClass(), "/report");
//设置异常处理器 这样的话 即使没有属性也不会出错 如:${list.name}...不会报错
config.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
try {
if(templateName.endsWith(".ftl")) {
templateName = templateName.substring(0, templateName.indexOf(".ftl"));
}
Template template = config.getTemplate(templateName + ".ftl");
response.setContentType("application/msword");
response.setHeader("Content-disposition", "attachment;filename="+ URLEncoder.encode(fileName, "utf-8"));
OutputStream outputStream = response.getOutputStream();
Writer out = new BufferedWriter(new OutputStreamWriter(outputStream));
//将模板中的预先的代码替换为数据
template.process(dataMap, out);
log.info("由模板文件:" + templateName + ".ftl" + " 生成Word文件 " + fileName + " 成功!!");
out.flush();
} catch (TemplateNotFoundException e) {
log.info("模板文件未找到");
e.printStackTrace();
} catch (MalformedTemplateNameException e) {
log.info("模板类型不正确");
e.printStackTrace();
} catch (TemplateException e) {
log.info("填充模板时异常");
e.printStackTrace();
} catch (IOException e) {
log.info("IO异常");
e.printStackTrace();
}
}
}
代码大致如上,还有个问题,正常属性好像不能用对象,但是可以用列表list
如果要使用list,需要另外设置,设置如下
(我用的是笨方法,在修改为ftl之后手动添加list的,不知道其他方法行不行),截图如下
大致格式如下,可复制修改
<#list listTotol as notice>
例如时间:${notice.Day}
关于自增序号的是:${notice_index+1}
#list>
三、 Word模板的转换方法
设置好域的word文档另存问xml,选择2003的哪个,然后重命名为ftl,复制ftl里面内容,增加上面需要的list标签,不需要列表可不加。
四、参考连接
https://blog.csdn.net/plxddyxnmd/article/details/10912983ss
本方法只是记录我遇到的问题以及解决,不是适合所有的方法



