通过maven引入须要的依赖

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

创立导出模版

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

word模版地址:http://file.xiaoxiaofeng.site/files/word.doc

留神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文件,查看咱们的占位符是否规范

留神:占位符有时候会产生被隔开的状况,如下图:

图片的替换同下面的阐明,图片为一串长长的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进去了呦。

导出效果图如下:

对于笑小枫

本章到这里完结了,喜爱的敌人关注一下我呦,大伙的反对,就是我保持写下去的能源。

微信公众号:笑小枫

笑小枫集体博客:https://www.xiaoxiaofeng.com

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