Java项目中利用Freemarker模板引擎导出

您所在的位置:网站首页 freemarker生成word首行缩进 Java项目中利用Freemarker模板引擎导出

Java项目中利用Freemarker模板引擎导出

2024-06-09 06:32| 来源: 网络整理| 查看: 265

应邀写的一篇文章:Java项目中利用Freemarker模板引擎导出--生成Word文档 资源下载:https://download.csdn.net/download/weixin_41367523/85051104 在项目中难免和各种数据报表打交道,如导出XX申请表,登记表,推荐表之类。就可以通过现有信息导出Word文档。基于Java语言来导出Word文档的方式也有很多种,如Jacob,Apache POI,Freemarker,PageOffice,java2word 等等。。。。

在这里将通过Freemarker这个模板引擎来实现导出 Word,项目不限于Swing,SSH,SSM,Spring Boot 之类的。。。。。。。。。。

Freemarker介绍

首先说一下Freemarker是个什么东西:

       FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。       FreeMarker是免费的,基于Apache许可证2.0版本发布。其模板编写为FreeMarker Template Language(FTL),属于简单、专用的语言。需要准备数据在真实编程语言中来显示,比如数据库查询和业务运算, 之后模板显示已经准备好的数据。在模板中,主要用于如何展现数据, 而在模板之外注意于要展示什么数据 [1] 。                                                                                                 ------百度百科 总的来说:模板 + 数据模型 = 输出

看不懂也没关系,看一个简单的例子:通常我们在Java Web开发的时候,实现一个JSP页面的输出需要编写一个JSP文件《xxxx.jsp》,实际上这个JSP文件主要包含了两部分内容: HTML+CSS+JavaScript构成的页面框架 + 用来动态显示数据库数据的Java代码(一般来说直接写Java代码是非常不美观且修改复杂的事情,不符合MVC开发模式,所以会用JSTL标签来代替直接写Java代码)

静态标签-模板 动态数据-数据模型 HTML 网页框架代码 CSS JavaScript 后端数据 JSTL标签填充 完整的JSP动态页面

在这里插入图片描述在Freemarker中也有一套类似于JSTL的标签,其实简单来说freemarker就是用来代替jsp来做处理,因为我们如果用JSP的话,是需要WEB容器的,如tomcat,JSP在第一次执行的时候会被编译转换成Servlet类,之后的每次修改都要编译和转换。而FreeMarker模板技术并不存在编译和转换的问题,并且与容器无关。我们在非web项目下也没必要再引入一个web容器了。

静态标签-模板 动态数据-数据模型 空白Word文档 XML代码 后端数据 FTL标签填充 完整的Word文档 示例用的项目搭建

下面进入正题: 首先创建一个项目,在这里的项目可以为Java swing,Javaweb的SSM,Springboot等项目都是没问题的。我还是直接用SpringBoot项目实现这个功能了。 首先用IDEA创建一个Spring Boot项目 在这里插入图片描述用其他IDE的也可以在https://start.spring.io网站上面直接下载一个springboot项目 在这里插入图片描述下一步填完信息,这里我用默认的信息了 在这里插入图片描述开始选择所需要的插件依赖,也就是jar包,都是通过maven管理的,上图有说明 1. 在这里插入图片描述2. 选择Spring Web,就是SpringMVC 在这里插入图片描述3. 选择用哪个模板引擎,这里用Freemarker 在这里插入图片描述4. 选择数据库框架,这里用mybaits+mysql 在这里插入图片描述5. 下一步,选择项目路径,点击完成就可以了 在这里插入图片描述Freemarker主要依赖的jar包是

# Springboot 提供的 org.springframework.boot spring-boot-starter-freemarker # 也可以选择其他版本如: org.freemarker freemarker 2.3.30 # 网址: https://mvnrepository.com/artifact/org.freemarker/freemarker FTL模板制作

项目搭建好之后,开始制作FTL模板,这次选择一个XXX推荐表来实现: 如Word文档: 在这里插入图片描述开始制作模板: 首先,我们需要在模板上面添加占位符,${XXXXX}。这里全用了拼音简写 在这里插入图片描述添加好占位符之后,将该Word文档另存为XML格式的文件 在这里插入图片描述修改一下文件名称,保存在这里插入图片描述即得到一个XML文件 在这里插入图片描述 打开观察一下,正常 在这里插入图片描述接下来,利用文本编辑器打开这个文件,如Notepad++、Sublime Text、EditPlus、UltraEdit什么都行,我这里用VSCode。如图 在这里插入图片描述

直接搜索前面添加的占位符${xxxx},这里可能会出现一些问题,如符号和花括号分离,这时候就得对它进行修改,恢复原样 在这里插入图片描述修改后 在这里插入图片描述等检查一遍没问题之后呢,就修改完成了,开始进入下一步修改文件后缀 在这里插入图片描述在这里插入图片描述

代码编写

接下来开始代码编写部分,一般来说这里都是用数据库的数据作为导出数据。但由于麻烦就不写数据库部分了,在这里直接用提交表单的数据来进行导出。

回到项目上,新建一个实体类,TableData.java ,将占位符标识作为类属性,生成get、set方法。。。。。发现院系YX和邮箱YX重复了,修改邮箱为DZYX

在这里插入图片描述2. 新建简单的测试页面 在这里插入图片描述 3. 编写导出工具类

首先将实体类封装为导出数据所需的map,创建数据模型 在这里插入图片描述**注意:**在这里直接用的是封装实体类,所以在模板里面也需要改一下占位符,在前面加上对象名${DZYX}变为${tableData.DZYX},用文本编辑器一键搜索${替换即可 在这里插入图片描述在这里插入图片描述

编写方法,创建freeMarker配置实例,创建数据模型,加载模板,输出

/** * 导出Word文件 * * @param tableData * @param request * @param response * @throws Exception */ public InputStreamSource exportToWord(TableData tableData, HttpServletRequest request, HttpServletResponse response) throws Exception { // 纠正编码 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("utf-8"); // ** 初始化配置文件**//* Configuration configuration = new Configuration(); // ** 设置编码 **//* configuration.setDefaultEncoding("utf-8"); // ** ftl文件的路径**//* String fileDirectory = "D:\\"; //将模板文件放到了D盘下 // 加载模板文件 configuration.setDirectoryForTemplateLoading(new File(fileDirectory)); // 加载模板,通过Word转XML文件转换过来的 Template template = configuration.getTemplate("FreemarkerTest.ftl"); // 准备数据 Map dataMap = data(tableData); // 指定输出word文件的路径 // 调用工具类WordUtils的createDoc方法生成Word文档 InputStreamSource file = UtilTest.createDoc(dataMap, template); InputStream fin = file.getInputStream(); ServletOutputStream out; response.setContentType("application/msword"); // 设置浏览器以下载的方式处理该文件 response.setHeader("content-disposition", "attachment;filename=document.doc"); out = response.getOutputStream(); // 缓冲区 byte[] buffer = new byte[512]; int bytesToRead; // 通过循环将读入的Word文件的内容输出到浏览器中 while ((bytesToRead = fin.read(buffer)) != -1) { out.write(buffer, 0, bytesToRead); } fin.close(); if (out != null) { out.close(); } return file; }

创建word文件

/** * 创建word文件 * * @param dataMap * @param template * @return * @throws TemplateException * @throws IOException */ public static InputStreamSource createDoc(Map dataMap, Template template) throws TemplateException, IOException { //生成随机的合同名称 StringWriter out1 = new StringWriter(); Writer out = new BufferedWriter(out1, 10240); //将数据输出到模板 template.process(dataMap, out); out.close(); out1.close(); return new ByteArrayResource(out1.toString().getBytes(StandardCharsets.UTF_8)); } 编写控制层 在这里插入图片描述 运行项目,跳到测试页面,填写相应信息 在这里插入图片描述 提交表单,会弹出下载框 在这里插入图片描述 将文件下载到本地,打开,可以看到已经填充完成, 在这里插入图片描述至此,基于Java和freemarker实现的Word文件导出功能已经实现了 再回顾一下步骤:

编辑好格式的Word文档 1份

将Word文档里需要填充的地方加上占位符${xxxx}

将编辑好占位符的文档另存为XML格式Word 2003 XML文档,并重命名,用英文命名

利用文本编辑器打开该XML文件检查,搜索第二步编辑的占位符,遇到$和 { } 分离的情况则进行修改。检查完毕后保存退出。

将检查完成的XML文件修改后缀名为 xxx.ftl

模板编辑完成

建立Java项目,引入jar包

org.freemarker freemarker 2.3.30 编写对应数据的实体类编写测试页面编写导出的工具类(核心),并修改模板对应的占位符,有需要的话编写控制层测试 代码

项目代码–工具类

package com.hh.onlinelearning.util; import com.hh.onlinelearning.entity.TableData; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.InputStreamSource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; public class UtilTest { /** * 导出Word文件 * * @param tableData * @param request * @param response * @throws Exception */ public InputStreamSource exportToWord(TableData tableData, HttpServletRequest request, HttpServletResponse response) throws Exception { // 纠正编码 request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("utf-8"); // ** 初始化配置文件**//* Configuration configuration = new Configuration(); // ** 设置编码 **//* configuration.setDefaultEncoding("utf-8"); // ** ftl文件的路径**//* String fileDirectory = "D:\\"; // 加载模板文件 configuration.setDirectoryForTemplateLoading(new File(fileDirectory)); // 加载模板,通过Word转XML文件转换过来的 Template template = configuration.getTemplate("FreemarkerTest.ftl"); // 准备数据 Map dataMap = data(tableData); // 指定输出word文件的路径 // 调用工具类WordUtils的createDoc方法生成Word文档 InputStreamSource file = UtilTest.createDoc(dataMap, template); InputStream fin = file.getInputStream(); ServletOutputStream out; response.setContentType("application/msword"); // 设置浏览器以下载的方式处理该文件 response.setHeader("content-disposition", "attachment;filename=document.doc"); out = response.getOutputStream(); // 缓冲区 byte[] buffer = new byte[512]; int bytesToRead; // 通过循环将读入的Word文件的内容输出到浏览器中 while ((bytesToRead = fin.read(buffer)) != -1) { out.write(buffer, 0, bytesToRead); } fin.close(); if (out != null) { out.close(); } return file; } /** * 构造数据,key-value * * @param tableData * @return */ public Map data(TableData tableData) { Map dataMap = new HashMap(); dataMap.put("tableData", tableData); return dataMap; } /** * 创建word文件 * * @param dataMap * @param template * @return * @throws TemplateException * @throws IOException */ public static InputStreamSource createDoc(Map dataMap, Template template) throws TemplateException, IOException { //生成随机的合同名称 StringWriter out1 = new StringWriter(); Writer out = new BufferedWriter(out1, 10240); //将数据输出到模板 template.process(dataMap, out); out.close(); out1.close(); return new ByteArrayResource(out1.toString().getBytes(StandardCharsets.UTF_8)); } }

控制层代码:

/** * 提交表单,下载Word文件 * @param tableData * @param request * @param response * @return * @throws Exception */ @PostMapping("/export") public String a(TableData tableData, HttpServletRequest request, HttpServletResponse response) throws Exception { UtilTest u = new UtilTest(); u.exportToWord(tableData,request,response); return ""; } /** * 跳转到表单填写页 * @return */ @GetMapping("/") public String index() { return "/upload"; }

实体类代码:

package com.hh.onlinelearning.entity; /** * 对应Word文档的占位符,实体类 */ public class TableData { private int id; private String XM; private String XB; private String MZ; private String CSNY; private String ZZMM; private String YX; private String ZY; private String SYD; private String XL; private String XW; private String DH; private String SG; private String TZ; private String DZYX; private String SLZ; private String SLY; private String LXDZ; private String WY; private String JSJ; private String JYYX; private String AH; private String JWJD; private String SHSJ; private String RZQK; private String HJQK; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getXM() { return XM; } public void setXM(String XM) { this.XM = XM; } public String getXB() { return XB; } public void setXB(String XB) { this.XB = XB; } public String getMZ() { return MZ; } public void setMZ(String MZ) { this.MZ = MZ; } public String getCSNY() { return CSNY; } public void setCSNY(String CSNY) { this.CSNY = CSNY; } public String getZZMM() { return ZZMM; } public void setZZMM(String ZZMM) { this.ZZMM = ZZMM; } public String getYX() { return YX; } public void setYX(String YX) { this.YX = YX; } public String getZY() { return ZY; } public void setZY(String ZY) { this.ZY = ZY; } public String getSYD() { return SYD; } public void setSYD(String SYD) { this.SYD = SYD; } public String getXL() { return XL; } public void setXL(String XL) { this.XL = XL; } public String getXW() { return XW; } public void setXW(String XW) { this.XW = XW; } public String getDH() { return DH; } public void setDH(String DH) { this.DH = DH; } public String getSG() { return SG; } public void setSG(String SG) { this.SG = SG; } public String getTZ() { return TZ; } public void setTZ(String TZ) { this.TZ = TZ; } public String getDZYX() { return DZYX; } public void setDZYX(String DZYX) { this.DZYX = DZYX; } public String getSLZ() { return SLZ; } public void setSLZ(String SLZ) { this.SLZ = SLZ; } public String getSLY() { return SLY; } public void setSLY(String SLY) { this.SLY = SLY; } public String getLXDZ() { return LXDZ; } public void setLXDZ(String LXDZ) { this.LXDZ = LXDZ; } public String getWY() { return WY; } public void setWY(String WY) { this.WY = WY; } public String getJSJ() { return JSJ; } public void setJSJ(String JSJ) { this.JSJ = JSJ; } public String getJYYX() { return JYYX; } public void setJYYX(String JYYX) { this.JYYX = JYYX; } public String getAH() { return AH; } public void setAH(String AH) { this.AH = AH; } public String getJWJD() { return JWJD; } public void setJWJD(String JWJD) { this.JWJD = JWJD; } public String getSHSJ() { return SHSJ; } public void setSHSJ(String SHSJ) { this.SHSJ = SHSJ; } public String getRZQK() { return RZQK; } public void setRZQK(String RZQK) { this.RZQK = RZQK; } public String getHJQK() { return HJQK; } public void setHJQK(String HJQK) { this.HJQK = HJQK; } }

HTML测试页:

DOCTYPE html> 测试 测试

freemarker 各个版本的jar包:Maven仓库



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3