文章目录
一、文章背景
公司的某个需求,需要根据接口的信息生成一份word接口文档信息并支持导出功能。以前没做过这种需求,于是搜罗各种资料,最终发现java利用freemarker模版可以实现这个功能。
二、实现步骤
1、需要的环境
org.springframework.boot spring-boot-starter-parent 2.0.6.RELEASE org.springframework.boot spring-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集合遍历的形式动态展示,所以需要遍历列表标签并展示数据。遍历的语法如下:<#list 集合 as 对象名> #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(); } 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 { @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> 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文件异常。
来源地址:https://blog.csdn.net/qq_45087487/article/details/129836101