在项目中经常会遇到报表相关的需求,而大多数会以excel出现,今天咱们说说word导出的一些事
文章目录
目录
简单介绍
freemarker+ftl
xdocreport开源工具
一、freemarker导出word步骤
二、xdocreport导出word步骤
三、常见语法介绍
四、Poi-tl开源工具
总结
前言
Java对word导出支持不太友好,由于本人水平有限,知道两种方式生成word文件。
1.freemarker+ftl
2.xdocreport开源工具
引入freemarker包,准备好需要生成word模板的ftl文件。该文件是有word生成xml,在由xml修改后缀名得到的temp.ftl文件
org.springframework.boot
spring-boot-starter-freemarker
缺点:word —>xml —>ftl 的过程繁琐且容易出错,ftl为标签内容不易读,如果模板变更又要重复word —>xml —>ftl 的过程。需要强大的内心和耐心。
该开源工具填写word模板语法一致,但不需要生成ftl文件作为模板,本身word就可直接作为导出模板。
fr.opensagres.xdocreport
fr.opensagres.xdocreport.template.freemarker
2.0.2
fr.opensagres.xdocreport
fr.opensagres.xdocreport.document.docx
2.0.2
优点:可读性提高,修改模板是可以增量操作,无需复杂操作再次生成ftl文件
private void exportDoc(String fileName, HttpServletResponse response, String tempName) {
PrintWriter writer = null;
Map dataMap = new HashMap<>();
// 将要写入模板的数据塞到dataMap中。
dataMap.put("name":"i am kobe");
try {
Configuration configuration = new Configuration(new Version("2.3.0"));
configuration.setDefaultEncoding("utf-8");
// 上面配置模板的路径
configuration.setClassForTemplateLoading(DocServiceImpl.class, "/templates");
configuration.setTemplateLoader(new ClassTemplateLoader(DocServiceImpl.class, "/templates"));
response.setContentType("application/msword");
response.setHeader("Content-Disposition", "attachment;filename=\"" + new String(fileName.getBytes("GBK"), "ISO-8859-1") + "\"");
response.setCharacterEncoding("utf-8");
writer = response.getWriter();
// tempName是模板的文件名称
Template template = configuration.getTemplate(tempName, "utf-8");
template.process(dataMap, writer);
} catch (Exception e) {
logger.error("导出word文档异常 : {}", e);
} finally {
writer.flush();
writer.close();
}
}
这样就完成了freemarker配置以及下载word文档的功能了。
public void download(HttpServletRequest request,HttpServletResponse response){
try{
InputStream inputStream = new FileInputStream(new File("D:\\template.docx"));
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(inputStream, TemplateEngineKind.Freemarker);
IContext context = report.createContext();
report.setFieldsMetadata(fieldsMetadata);
//替换word模板中创建的域的变量
context.put("name", "我叫张三");
//导出word
ByteArrayOutputStream bout = new ByteArrayOutputStream();
// 获取OutputStream 也就是写入bout
report.process(context, bout);
//创建文件输出流
FileOutputStream out = new FileOutputStream("d:\\daochudeword.docx");
out.write(bout.toByteArray());
out.close();
bout.close();
} catch (Exception e) {
e.printStackTrace();
}
}
使用才是开始,语法才是修行。xdocreport的语法是兼容freemarker的。
if判断的使用,下面是判断list集合是否为空且长度是否大于0
[#if list?? && (list?size>0)]
[#else]
list 集合为空
[/#if]
[#if list?? && (list?size>0)]
[/#if]
对象判空
[#if obj??]
[/#if]
数组的使用,循环输出多条数据
[#list list as temp]
${temp}
[/#list]
pom.xml包引入
com.deepoove
poi-tl
1.12.0
public static void main(String[] args) {
Map params = new HashMap<>();
// 渲染文本
params.put("dep","知识研发中心");
params.put("apply_man","知识追寻者");
params.put("project","搭建个人网站 https://zszxz.com/index 费用");
params.put("money","19998");
params.put("count","8");
params.put("year","2020");
params.put("month","02");
params.put("day","8");
// 模板路径
String templatePath = "C:/mydata/generator/demo/template.docx";
// 生成word的路径
String fileDir = "C:/mydata/generator/demo";
// 生成word的文件
String fileName = "zszxz.docx";
String wordPath = createWord(templatePath, fileDir, fileName, params);
System.out.println("生成文档路径:" + wordPath);
}
private static Logger logger = LoggerFactory.getLogger(TemplateController.class);
/**
* @author lsc
* @param templatePath word模板文件路径
* @param fileDir 生成的文件存放地址
* @param fileName 生成的文件名
* @param paramMap 参数集合
* @return 返回word生成的路径
*/
public static String createWord(String templatePath, String fileDir, String fileName, Map paramMap) {
Assert.notNull(templatePath, "word模板文件路径不能为空");
Assert.notNull(fileDir, "生成的文件存放地址不能为空");
Assert.notNull(fileName, "生成的文件名不能为空");
File dir = new File(fileDir);
if (!dir.exists()) {
logger.info("目录不存在,创建文件夹{}!", fileDir);
dir.mkdirs();
}
String filePath = fileDir +"\\"+ fileName;
// 读取模板渲染参数
XWPFTemplate template = XWPFTemplate.compile(templatePath).render(paramMap);
try {
// 将模板参数写入路径
template.writeToFile(filePath);
template.close();
} catch (Exception e) {
logger.error("生成word异常{}", e.getMessage());
e.printStackTrace();
}
return filePath;
}
很多语法不是很常用,if和list是本人在项目中运用的较多的,后续会及时更新相关语法。
Poi-tl 开源工具兼容性更好、操作更加简单、文档根据齐全,非常之方便 Poi-tl Documentation