【笑小枫的SpringBoot系列】【十五】SpringBoot根据模板生成Word

简介: 【笑小枫的SpringBoot系列】【十五】SpringBoot根据模板生成Word

通过maven引入需要的依赖


<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>


创建导出模版


1、首先创建一个word模版文档,模版如下图


word模版地址:点击下载

注意word中的占位符的格式,就是freemaker的格式

详细解释如下:

  • 文字处理:


直接用${} 中间为替换的字段名。


如果直接在word里面定义${title},在转换成xml的时候有可能会被一些编码隔开,这个时候只需要用word打开xml,将这些内容重新输入一遍。


强烈建议用IDE打开,然后格式化下,在进行检查处理,能用搜索尽量搜索,xml的格式里面有太多的代码,不要硬刚😂


  • 图片处理:

需要在word文档模版中插入图片

将word转换成xml后,打开xml,会将我们的图片转换成长长的一段base64。

我们把base64换成我们的${pic}就可以了,pic为字段名,可任意替换


  • 列表处理:

需要在word文档模版中插入表格

找到第二个<w:tr>,第一行是我们的标题,在其前面添加 <#list peopleList as list> 其中 peopleList是传入list的集合名称 list 是别名。

参数取值为:${list.name}这样。

在与<w:tr>配对的</w:tr>后面添加</#list>。 语法同freemaker的for循环语法

创建ftl模板


将上述word文档另存为test.xml格式,另存完之后可以用浏览器打开test.xml文件,查看我们的占位符是否标准


注意:占位符有时候会发生被隔开的情况,如下图:


651009bcf5915fb0388f84341c9f7b4d.png

图片的替换同上面的说明,图片为一串长长的base64,如下图所示:


然后将文件放置resources/templates目录下。

放置在resource目录下即可,剩下的目录根据自己需求定制。注意要与WordUtil.java中的目录对应。


编写程序


通用的导出工具类


在util包下创建WordUtil.java工具类,👇

package com.maple.demo.util;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import static freemarker.template.Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS;
/**
 * @author 笑小枫
 * @date 2022/7/27
 * @see <a href="https://www.xiaoxiaofeng.com">https://www.xiaoxiaofeng.com</a>
 */
public class WordUtil {
    private final Configuration configuration;
    public WordUtil() {
        configuration = new Configuration(DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        configuration.setDefaultEncoding("UTF-8");
    }
    public void createWord(Map<String, Object> dataMap, String templateName, String fileName) {
        // 模板文件所在路径
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");
        Template t = null;
        try {
            // 获取模板文件
            t = configuration.getTemplate(templateName, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 导出文件
        File outFile = new File(fileName);
        try (Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), StandardCharsets.UTF_8))) {
            if (t != null) {
                // 将填充数据填入模板文件并输出到目标文件
                t.process(dataMap, out);
            }
        } catch (IOException | TemplateException e1) {
            e1.printStackTrace();
        }
    }
}

请求接口

controller包下创建TestWordController.java👇

其中用到了之前文章的文件转base64,参考文章15.Base64与File互转

package com.maple.demo.controller;
import com.maple.demo.util.Base64Util;
import com.maple.demo.util.WordUtil;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.*;
/**
 * @author 笑小枫
 * @date 2022/7/27
 * @see <a href="https://www.xiaoxiaofeng.com">https://www.xiaoxiaofeng.com</a>
 */
@RestController
@AllArgsConstructor
@RequestMapping("/example")
@Api(tags = "实例演示-根据模板生成word")
public class TestWordController {
    /**
     * 文字处理:
     * 直接用${} 中间为替换的字段名。
     * 如果直接在word里面定义${title},在转换成xml的时候有可能会被一些编码隔开,这个时候只需要用word打开xml,将这些内容重新输入一遍。
     * 可以用浏览器打开xml,检出自己定义的${}的内容是否都在一起,是否有被编码隔开的情况。
     * 图片处理:
     * 需要在word文档模版中插入图片
     * 将word转换成xml后,打开xml,会将我们的图片转换成长长的一段base64。
     * 我们把base64换成我们的${pic}就可以了,pic为字段名,可任意替换
     * 列表处理:
     * 需要在word文档模版中插入表格
     * 找到第二个<w:tr>,在其前面添加 <#list peopleList as list> 其中 peopleList是传入list的集合名称 list 是别名。
     * 参数取值为:${list.name}这样。
     * 在与<w:tr>配对的</w:tr>后面添加</#list>。 语法同freemaker的for循环语法
     */
    @GetMapping("/exportWord")
    public void exportWord(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 1.创建临时文件夹
        String rootPath = request.getSession().getServletContext().getRealPath("/");
        String fileName = UUID.randomUUID().toString().replace("-", "");
        // 处理图片信息,将图片转为base64字符串
        File imageFile = new File("D:\\xiaoxiaofeng.jpg");
        String base64 = Base64Util.fileToBase64(imageFile);
        // 处理表格的数据信息
        List<Map<String, Object>> list = new ArrayList<>();
        int size = 5;
        for (int i = 0; i < size; i++) {
            Map<String, Object> map = new HashMap<>(16);
            map.put("nickName", "笑小枫" + i);
            map.put("visitTime", "2022-07-27");
            map.put("isLike", "是");
            map.put("isAttention", "是");
            list.add(map);
        }
        // 加载word中的数据信息
        WordUtil word = new WordUtil();
        Map<String, Object> dataMap = new HashMap<>(16);
        dataMap.put("title", "记得关注我哟");
        dataMap.put("email", "1150640979@qq.com");
        dataMap.put("name", "笑小枫");
        dataMap.put("createDate", "2022-07-27");
        dataMap.put("pic", base64);
        dataMap.put("peopleList", list);
        word.createWord(dataMap, "word.xml", rootPath + "/" + fileName + ".doc");
        String exportName = "测试word";
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/msword");
        // 设置浏览器以下载的方式处理该文件名
        response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(exportName + ".doc", "UTF-8"))));
        File file = new File(rootPath + "/" + fileName + ".doc");
        try (InputStream fin = new FileInputStream(file);
             ServletOutputStream out = response.getOutputStream()) {
            // 缓冲区
            byte[] buffer = new byte[512];
            int bytesToRead;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while ((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 删除临时文件
            file.delete();
        }
    }
}

测试


在浏览器输入http://localhost:6666/example/exportWord便可以看到你的word出来了呦。

导出效果图如下:

790ba3f59f91a1b89a03ecfa89a5b71d.png


关于笑小枫💕


本章到这里结束了,喜欢的朋友关注一下我呦😘😘,大伙的支持,就是我坚持写下去的动力。

笑小枫个人博客:https://www.xiaoxiaofeng.com

本文源码:https://github.com/hack-feng/maple-demo


本系列其它文章


本系列的源码已同步在Github:https://github.com/hack-feng/maple-demo


  1. SpringBoot项目创建
  2. SpringBoot配置基于swagger2的knife4j接口文档
  3. SpringBoot集成Mybatis Plus
  4. SpringBoot返回统一结果包装
  5. SpringBoot返回统一异常处理
  6. SpringBoot日志打印Logback详解
  7. SpringBoot控制台自定义banner
  8. SpringBoot集成Redis
  9. SpringBoot用户登录拦截器
  10. SpringBoot处理请求跨域问题
  11. SpringBoot接口日志信息统一记录
  12. SpringBoot导入Excel
  13. SpringBoot导出Excel
  14. SpringBoot发送邮件
  15. SpringBoot根据模板生成Word
  16. SpringBoot生成PDF
  17. SpringBoot文件上传下载
  18. SpringBoot中的Properties配置
目录
相关文章
|
3月前
|
Java
Springboot 导出word,动态填充表格数据
Springboot 导出word,动态填充表格数据
|
3月前
|
前端开发 Java
SpringBoot下载xlsx模板,导出excel数据
SpringBoot下载xlsx模板,导出excel数据
266 0
|
Java Maven
springboot项目--freemarker使用ftl模板文件动态生成图片
springboot项目--freemarker使用ftl模板文件动态生成图片
491 0
|
3月前
|
XML JavaScript 前端开发
springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】
springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】
|
3月前
|
存储 Java Apache
Spring Boot整合OpenOffice实现Word、Excel、PPT在线预览
Spring Boot整合OpenOffice实现Word、Excel、PPT在线预览
273 0
|
12月前
|
前端开发 Java
SpringBoot-6-模板Thymeleaf常用标签
SpringBoot-6-模板Thymeleaf常用标签
69 0
SpringBoot-6-模板Thymeleaf常用标签
|
3月前
|
算法 Java
制作SpringBoot工程模板
制作SpringBoot工程模板
42 0
|
3月前
|
移动开发 运维 前端开发
SpringBoot 整合 Thymeleaf & 如何使用后台模板快速搭建项目
SpringBoot 整合 Thymeleaf & 如何使用后台模板快速搭建项目
79 0
|
3月前
|
Oracle Java 关系型数据库
Generator【SpringBoot集成】代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)
Generator【SpringBoot集成】代码生成+knife4j接口文档(2种模板设置、逻辑删除、字段填充 含代码粘贴可用)保姆级教程(注意事项+建表SQL+代码生成类封装+测试类)
67 0
|
8月前
|
Java
application.properties模板+application.yml模板+pom模板+mapper.xml模板(springboot)
application.properties模板+application.yml模板+pom模板+mapper.xml模板(springboot)
56 0