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

  1. 导入pom依赖

             <!--freemarker模板依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-freemarker</artifactId></dependency>
  2. 模板文件生成, 新建word文档模板,另存为.xml文件,修改后缀为.ftl

在当前项目中导入模板文件 ctrl+alt+l格式化

选择你需要修改的地方,进行修改

声明接口和实现

  • 导出word工具类
/*** 导出word工具类*/
public class WordUtils {private static Configuration configuration = null;static {configuration = new Configuration(Configuration.VERSION_2_3_0);configuration.setDefaultEncoding("utf-8");configuration.setClassForTemplateLoading(WordUtils.class, "/template");}/*** 导出word** @param response 响应流* @param title    导出的文件名称*/public static void export(HttpServletResponse response, Map<?, ?> map, String title, String templateName) {File file;Template freemarkerTemplate;try {freemarkerTemplate = configuration.getTemplate(templateName);// 调用工具类的createDoc方法生成Word文档file = createDoc(map, freemarkerTemplate);response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);FileUtils.setAttachmentResponseHeader(response, title);FileUtils.writeBytes(file.getAbsolutePath(), response.getOutputStream());FileUtils.deleteFile(file.getAbsolutePath());} catch (IOException e) {e.printStackTrace();}}/*** 创建word文档** @param dataMap  需要填入的字段* @param template 模板* @return 生成的模板文件*/public static File createDoc(Map<?, ?> dataMap, Template template) {String name = System.currentTimeMillis() + ".doc";File f = new File(name);try {Writer w = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f), StandardCharsets.UTF_8));template.process(dataMap, w);w.close();} catch (Exception ex) {throw new RuntimeException(ex);}return f;}}
  • 文件操作类
/*** 文件处理工具类* */
public class FileUtils
{public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";/*** 输出指定文件的byte数组* * @param filePath 文件路径* @param os 输出流* @return*/public static void writeBytes(String filePath, OutputStream os) throws IOException{FileInputStream fis = null;try{File file = new File(filePath);if (!file.exists()){throw new FileNotFoundException(filePath);}fis = new FileInputStream(file);byte[] b = new byte[1024];int length;while ((length = fis.read(b)) > 0){os.write(b, 0, length);}}catch (IOException e){throw e;}finally{IOUtils.close(os);IOUtils.close(fis);}}/*** 写数据到文件中** @param data 数据* @return 目标文件* @throws IOException IO异常*/public static String writeImportBytes(byte[] data) throws IOException{return writeBytes(data, BozConfig.getImportPath());}/*** 写数据到文件中** @param data 数据* @param uploadDir 目标文件* @return 目标文件* @throws IOException IO异常*/public static String writeBytes(byte[] data, String uploadDir) throws IOException{FileOutputStream fos = null;String pathName = "";try{String extension = getFileExtendName(data);pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);fos = new FileOutputStream(file);fos.write(data);}finally{IOUtils.close(fos);}return FileUploadUtils.getPathFileName(uploadDir, pathName);}/*** 删除文件* * @param filePath 文件* @return*/public static boolean deleteFile(String filePath){boolean flag = false;File file = new File(filePath);// 路径为文件且不为空则进行删除if (file.isFile() && file.exists()){file.delete();flag = true;}return flag;}/*** 文件名称验证* * @param filename 文件名称* @return true 正常 false 非法*/public static boolean isValidFilename(String filename){return filename.matches(FILENAME_PATTERN);}/*** 检查文件是否可下载* * @param resource 需要下载的文件* @return true 正常 false 非法*/public static boolean checkAllowDownload(String resource){// 禁止目录上跳级别if (StringUtils.contains(resource, "..")){return false;}// 检查允许下载的文件规则if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource))){return true;}// 不在允许下载的文件规则return false;}/*** 下载文件名重新编码* * @param request 请求对象* @param fileName 文件名* @return 编码后的文件名*/public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException{final String agent = request.getHeader("USER-AGENT");String filename = fileName;if (agent.contains("MSIE")){// IE浏览器filename = URLEncoder.encode(filename, "utf-8");filename = filename.replace("+", " ");}else if (agent.contains("Firefox")){// 火狐浏览器filename = new String(fileName.getBytes(), "ISO8859-1");}else if (agent.contains("Chrome")){// google浏览器filename = URLEncoder.encode(filename, "utf-8");}else{// 其它浏览器filename = URLEncoder.encode(filename, "utf-8");}return filename;}/*** 下载文件名重新编码** @param response 响应对象* @param realFileName 真实文件名*/public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException{String percentEncodedFileName = percentEncode(realFileName);StringBuilder contentDispositionValue = new StringBuilder();contentDispositionValue.append("attachment; filename=").append(percentEncodedFileName).append(";").append("filename*=").append("utf-8''").append(percentEncodedFileName);response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");response.setHeader("Content-disposition", contentDispositionValue.toString());response.setHeader("download-filename", percentEncodedFileName);}/*** 百分号编码工具方法** @param s 需要百分号编码的字符串* @return 百分号编码后的字符串*/public static String percentEncode(String s) throws UnsupportedEncodingException{String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());return encode.replaceAll("\\+", "%20");}/*** 获取图像后缀* * @param photoByte 图像数据* @return 后缀名*/public static String getFileExtendName(byte[] photoByte){String strFileExtendName = "jpg";if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)){strFileExtendName = "gif";}else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)){strFileExtendName = "jpg";}else if ((photoByte[0] == 66) && (photoByte[1] == 77)){strFileExtendName = "bmp";}else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)){strFileExtendName = "png";}return strFileExtendName;}/*** 获取名称* * @param fileName 路径名称* @return 没有文件路径的名称*/public static String getName(String fileName){if (fileName == null){return null;}int lastUnixPos = fileName.lastIndexOf('/');int lastWindowsPos = fileName.lastIndexOf('\\');int index = Math.max(lastUnixPos, lastWindowsPos);return fileName.substring(index + 1);}
}
  • controller层测试
/*** @description: 导出模板文件* @author: lsl* @time: 2022/3/18 11:45*/
@RestController
@RequestMapping("/business/template")
public class DownLoadTemplateController {/*** 下载模板文件*/@GetMapping("/download")public void fileDownload(HttpServletResponse response) {HashMap<Object, Object> data = new HashMap<>();data.put("text1", "张三");WordUtils.export(response, data, "测试.doc", "test.ftl");}
}

postman接口测试

成功!

参考文档

Java FreeMarker生成word - 掘金

什么是 FreeMarker? - FreeMarker 中文官方参考手册

Spring Boot 结合 FreeMarker导出word文件相关推荐

  1. freemarker 导出word文件中包含图片

    最近做的工作中出现的问题记录 在使用freemarker导出word文件的时候,使用wps做模板,出现的情况与网上的情况不同. 在查看网上的例子和资料的时候,模板中的样子是类似于这样的 <w:p ...

  2. Spring boot集成freemarker导出excel

    使用Spring boot集成freemarker可以将一些复杂的excel表格导出 下面直接开始使用步骤: 1. 集成freemarker 在pom.xml文件中导入springfreemarker ...

  3. spring boot 根据模板导出word功能实现,包含html内容,及office打开乱码问题的解决!!!

    使用freemark来实现 yml配置文件: template-loader-path: classpath:/templates/ftl/ 这个是配置模板所在的位置 这里的配置要是带"/& ...

  4. ftl文件模板图片_使用Freemarker导出Word文档(包含图片)代码实现及总结

    本篇是关于利用FreeMarker导出Word的实现步骤. 优点:采用FreeMarker是导出Word的最佳实现,非常的灵活,能够按照自己指定的样式设置并输出内容,操作简单方便,代码实现也容易.代码 ...

  5. 使用freemarker模板引擎导出word文件

    目录 第一步:创建Word模板 第二步:整理好数据,核对好数据要填充的位置 第三步:使用工具类生成word文件 工具类: 第一步:创建Word模板 创建需要的模板 另存为:单一网页文件 文件名最好改为 ...

  6. 若依 springboot 使用freemarker生成word文件,并导出下载

    目录 freemarker生成word文件并导出 一.环境准备 二.编写代码 1.实体类 2.mapper.xml文件 3.mapper.java文件 4.Service.java 5.Service ...

  7. Java技术:SpringBoot集成FreeMarker生成word文件

                    今天给大家分享SpringBoot集成FreeMarker模板引擎生成word文件的用法,感兴趣的可以学一下,完整源码地址在文章末尾处,欢迎互相沟通交流! 一.什么是F ...

  8. Java使用freemarker导出word试卷

    使用了freemarker模板填充占位符的方式来生成word文档,支持跨平台. Java导出Word的五种方式 制作Word模板 将制作好的Word模板.docx另存为.xml格式,修改xml文件的内 ...

  9. spring boot之FreeMarker

    一.添加jar <dependency><groupId>org.springframework.boot</groupId><artifactId>s ...

最新文章

  1. lolfps高但画面不流畅_你吃鸡卡吗,超详细和平精英画面设置教程,解决卡顿,主播都在用...
  2. 国内外免费电子书(数学、算法、图像、深度学习、机器学习)
  3. jmeter插件监控cpu小节点
  4. scala语言示例_标有示例的Scala关键字
  5. docker -v 覆盖了容器中的文件_Docker容器之安装Mysql
  6. java基础案例教程试题,Java基础案例教程-中国大学mooc-试题题目及答案
  7. javascript动画系列 —— 切换图片(原生)
  8. 《Python cookbook》笔记二
  9. qregularexpression和qregexp的区别
  10. 系统目录WINDOWS下主要文件夹简介
  11. c语言黑色方块字符,打字符号,一个黑的方块怎么打?
  12. ireport分页后最后多一页空白页
  13. 矩阵的分解:满秩分解和奇异值分解
  14. html实现雪花飘落
  15. java的graphics2d_Java Graphics2D 使用详解 | 学步园
  16. 人工智能前景怎么样 用哪个开发语言比较好
  17. PgAdmin3 F7
  18. 公众号500篇文章分类和索引
  19. 新手php集成环境,php集成环境服务器xampp安装使用教程(适合第一次玩PHP的新手)...
  20. python 百度智能完善拆分识别收货人地址

热门文章

  1. 程序员到底有没有必要买一台阿里云服务器?
  2. iOS开发之Crash分析,以及收集
  3. 虚拟机开启系统蓝屏报错:“终止代码:SYSTEM_SERVICE_ECXEPTION“
  4. 电商核心业务功能测试分析
  5. ArrayList源码解读
  6. 高德地图面积测量小工具
  7. 高中以前的手绘作品,素描和水粉
  8. 杜国光博士,基于视觉的机器人抓取--物体定位,位姿估计到抓取估计课堂笔记
  9. 诺奖背后的一位女性:伯莎·冯·苏特娜
  10. Excle 取前几位数、中间几位数、后几位数的方法