文章目录

    • 一、文章背景
    • 二、实现步骤
      • 1、需要的环境
      • 2、创建模板
      • 3、书写java类
      • 4、测试
    • 三、freemarker技术点

一、文章背景

公司的某个需求,需要根据接口的信息生成一份word接口文档信息并支持导出功能。以前没做过这种需求,于是搜罗各种资料,最终发现java利用freemarker模版可以实现这个功能。

二、实现步骤

1、需要的环境

org.springframework.bootspring-boot-starter-parent2.0.6.RELEASE org.springframework.bootspring-boot-starter org.springframework.boot spring-boot-starter-freemarker

2、创建模板

1)展示word文档如下所示:

2)将word文档动态的参数替换成占位符,如下所示:

3)word另存为xml格式保存

4)将xml文件更改为ftl文件

3、书写java类

1)将上一步生成的ftl文件重命名cdsnUser.ftl放到resource目录的templates文件夹下面,并格式化文件

ps:
1.1)因用户列表是list集合遍历的形式动态展示,所以需要遍历列表标签并展示数据。遍历的语法如下:
1.2)注意此处对象别名要和生成word占位符的属性对应上,不然取不到值
1.3)标签是行的意思,遍历的范围要对,不然word打不开或者后台报错

2)新建User类

import lombok.Data;@Datapublic class User {private String name;private String sex;private String iphone;private String idcard;private String idNum;}

3)wordUtil工具类

import freemarker.template.Configuration;import freemarker.template.Template;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.*;import java.util.Map;public class WordUtil {//配置信息,代码本身写的还是很可读的,就不过多注解了private static Configuration configuration = null;// 这里注意的是利用WordUtils的类加载器动态获得模板文件的位置//private static final String templateFolder = wordUtils.class.getClassLoader().getResource("../../../../templates").getPath();private static final String templateFolder = WordUtil.class.getResource("/templates").getPath();static {configuration = new Configuration();configuration.setDefaultEncoding("utf-8");try {System.out.println(templateFolder);configuration.setDirectoryForTemplateLoading(new File(templateFolder));} catch (IOException e) {e.printStackTrace();}}private WordUtil() {throw new AssertionError();}/** * 导出excel * @param request 请求对象 * @param response 响应对象 * @param map word文档中参数 * @param wordName 为模板的名字例如xxx.ftl * @param fileName 是word 文件的名字 格式为:"xxxx.doc" * @param name 是临时的文件夹米名称 string类型 可随意定义 * @throws IOException */public static void exportMillCertificateWord(HttpServletRequest request, HttpServletResponse response, Map map, String wordName, String fileName, String name) throws IOException {Template freemarkerTemplate = configuration.getTemplate(wordName);File file = null;InputStream fin = null;ServletOutputStream out = null;try {// 调用工具类的createDoc方法生成Word文档file = createDoc(map,freemarkerTemplate,name);fin = new FileInputStream(file);response.setCharacterEncoding("utf-8");response.setContentType("application/x-download");fileName = new String(fileName.getBytes(), "ISO-8859-1");response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(fileName)));out = response.getOutputStream();byte[] buffer = new byte[512];// 缓冲区int bytesToRead = -1;// 通过循环将读入的Word文件的内容输出到浏览器中while((bytesToRead = fin.read(buffer)) != -1) {out.write(buffer, 0, bytesToRead);}} finally {if(fin != null) fin.close();if(out != null) out.close();if(file != null) file.delete();// 删除临时文件}}private static File createDoc(Map<" />, ?> dataMap, Template template, String name) {File f = new File(name);Template t = template;try {// 这个地方不能使用FileWriter因为需要指定编码类型否则生成的Word文档会因为有无法识别的编码而无法打开Writer w = new OutputStreamWriter(new FileOutputStream(f), "utf-8");t.process(dataMap, w);w.close();} catch (Exception ex) {ex.printStackTrace();throw new RuntimeException(ex);}return f;}}

4)Controller类

import com.example.word_download.dao.InterfaceWord;import com.example.word_download.dao.Parameter;import com.example.word_download.dao.User;import com.example.word_download.util.WordUtil;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;@RestController@RequestMapping("/testControllerDownload")public class wordController {/** * 测试用户列表word的初级 * @param request * @param response * @throws IOException */@GetMapping("/getWord")public void getWord(HttpServletRequest request, HttpServletResponse response) throws IOException {User user1 = new User();user1.setName("lisa");user1.setSex("girl");user1.setIphone("1243435512434");user1.setIdcard("4211821997909021");user1.setIdNum("12");User user2 = new User();user2.setName("tom");user2.setSex("boy");user2.setIphone("1243435512434");user2.setIdcard("4211821997909021");user2.setIdNum("12");ArrayList<User> users = new ArrayList<>();users.add(user1);users.add(user2);//HashMap<String, List> map1 = new HashMap();HashMap<String, Object> map = new HashMap<>();map.put("users",users);map.put("appName","用户信息");String wordName = "csdnUser.ftl";String fileName = "interfaceWord.doc";String name = "name";WordUtil.exportMillCertificateWord(request,response,map,wordName,fileName,name);}}

4、测试

1)启动springboot项目后,在浏览器地址栏中输入请求路径,即可生成word文档并下载。

2)word文档内容如下:

三、freemarker技术点

1、简介

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

2、常用语法

1、判断语法<#if condition>...<#elseif condition2>...<#elseif condition3>...<#else>...</#if>=========================ps:if 空值判断===========================// 当 photoList 不为空时<#if photoList" />?>...</#if>2、遍历语法<#list empList! as emp> ${emp.name!}</#list>

3、某些标签的意思

<w:tr>:行的标签<w:tbl>:表格的标签ps:了解某些特定标签在遍历的时候很方便排错

4、常见问题

1)如下,获取值没有进行空值判断,加入空值判断就可以去除,如2中空值语法判断所示。

2、生成word打不开,是标签或者遍历的位置加入不对,导致word文件异常。