IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot导出word模板并动态渲染数据 -> 正文阅读

[Java知识库]SpringBoot导出word模板并动态渲染数据

导出word模板并动态渲染数据


一、需求介绍

背景:需要导出word模板的时候,有些数据是动态或者图片等不确定因素的时候、根据需求定制好的模板要求填充数据,那么这个时候就需要进行根据word模板进行动态添加数据渲染出 word。

本文主要介绍:

1、SpringBoot导出word模板

2、SpringBoot导出word模板并且渲染动态数据

3、SpringBoot导出word模板包含list数据循环输出

4、SpringBoot导出word模板包含图片信息展示

二、依赖添加

    <!-- JSON-util -->
	<dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.72</version>
    </dependency>
	<!-- framework(主要根据模板引擎导出word使用)  -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>

三、制作模板

制作模板思路:

1、使用word2007或者WPS进行将模板除数据外的格式进行绘制出

2、使用templeat语法将需要动态数据的位置进行替换

3、另存为制作好的word文件为xml(word 2007xml)格式的文件

4、将生成好得到xml文件修改后缀名为.ftl文件并进行代码格式化

5、检查ftl文件中是否有格式错误信息并且设置循环列表的补充、完成图片信息base64的替换

  • 3.1 绘制word模板并填充数据动态语法

在这里插入图片描述

这里图片信息暂放一张图占位(后续会改)

  • 3.2 保存为xml格式

在这里插入图片描述

  • 3.4 修改后缀名

    我们在上一步骤另存为的时候就已经保存为xml格式,在保存的文件夹下找到后修改后缀名为ftl文件。

在这里插入图片描述

  • 3.5 检查并设置循环和图片信息格式

    将ftl文件拖到idea中进行检查格式和替换图片信息

在这里插入图片描述

将base64码替换成占位符

在这里插入图片描述

检查每一处占位符是否都正确,可能再转化后少括号或者 $ 之类的,正常补充添加调整后即可

在这里插入图片描述

完成对循环数组的代码补充

转成xml后找到固定的规律就是

<w:tr> </w:tr> :代表表格中的一行
<w:tc> </w:tc> :代表表格中的一个单元格

那么就需要在动态循环的地方进行添加list循环代码

这个的所有语法就是 framework 语法一样了。

在这里插入图片描述

以上就是模板制作的全过程。下面实现代码部分。

四、后端代码

package com.hebiyusheng.auxililaryreport.controller;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import sun.misc.BASE64Encoder;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 
 * @date 2022/5/30 - 20:28
 * @Motto "何必余生、及时行乐、Good luck mi"
 * @data
 * @entity
 * @Excprite
 */

@RestController
@RequestMapping("studentWord")
public class ReportController {


    /**
     * 根据模板导出word数据
     *
     * @param response
     * @return
     * @throws Exception
     */
    @GetMapping("word")
    public HttpServletResponse word(HttpServletResponse response) throws Exception {
        /** 初始化配置文件 **/
        Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        /** 设置编码 **/
        configuration.setDefaultEncoding("utf-8");
        /** 我的ftl文件是放在D盘的**/
        String fileDirectory = "D:\\Spring\\ismy-project\\auxiliary\\auxiliary-report\\src\\main\\resources\\template\\";
        /** 加载文件 **/
        configuration.setDirectoryForTemplateLoading(new File(fileDirectory));
        /** 加载模板 **/
        Template template = configuration.getTemplate("student.ftl");
        List<Map<String, Object>> itemList = new ArrayList<>();//科目
        for (int i = 0; i < 5; i++) {
            Map<String, Object> kemu = new HashMap<>();
            kemu.put("name","科目"+i);
            kemu.put("chengji",90+i);
            itemList.add(kemu);
        }
        Map<String, Object> mapList = new HashMap<>();//参数
        mapList.put("serialNo", "20220629");//编号
        mapList.put("name", "XX一中");//姓名
        mapList.put("pic", getImgFileToBase64("C:\\Users\\hebiy\\Desktop\\XXXX.jpg"));//图片
        mapList.put("itemList", itemList);//科目
        mapList.put("toloclass", "700");//总分

        //* 指定输出word文件的路径 *
        String outFilePath = "D:\\Spring\\ismy-project\\auxiliary\\auxiliary-report\\src\\main\\resources\\template\\" +(System.currentTimeMillis()) + ".doc";
        File docFile = new File(outFilePath);
        //创建输出流
        FileOutputStream fos = new FileOutputStream(docFile);
        //创建缓冲器
        Writer out = new BufferedWriter(new OutputStreamWriter(fos, "utf-8"), 10240);
        //导出word
        template.process(mapList, out);
        /*文件下载*/
        File file = new File(outFilePath);
        // 取得文件名。
        String filename = file.getName();
        //下载
        InputStream fis = new BufferedInputStream(new FileInputStream(outFilePath));
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();
        // 清空response
        response.reset();
        // 设置response的Header
        response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
        response.addHeader("Content-Length", "" + file.length());
        OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/octet-stream");
        toClient.write(buffer);
        toClient.flush();
        toClient.close();
        //关闭缓冲器
        if (out != null) {
            out.close();
        }
        System.out.println("下载完成......");
        return null;
    }


    /**
     * 读取图片转成base64
     * @param imgFile
     * @return
     */
    public static String getImgFileToBase64(String imgFile) {
        //将图片文件转化为字节数组字符串,并对其进行Base64编码处理
        InputStream inputStream = null;
        byte[] buffer = null;
        //读取图片字节数组
        try {
            inputStream = new FileInputStream(imgFile);
            int count = 0;
            while (count == 0) {
                count = inputStream.available();
            }
            buffer = new byte[count];
            inputStream.read(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    // 关闭inputStream流
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 对字节数组Base64编码
        return new BASE64Encoder().encode(buffer);
    }

}

五、效果展示

在这里插入图片描述
说明:代码补充可自行优化。数据部分可优化为数据库读取数据等,针对部署linux问题将读取配置文件和图片信息替换成linux支持格式即可。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-07-05 23:25:28  更:2022-07-05 23:27:02 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 15:28:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码