导出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);//导出wordtemplate.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();// 清空responseresponse.reset();// 设置response的Headerresponse.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支持格式即可。

SpringBoot导出word模板并动态渲染数据相关推荐

  1. 【Java】poi-tl实现导出Word模板并动态渲染数据

    文章目录 前言 优点 缺点 使用 引入依赖 渲染普通占位符 表格渲染 前言 最近做项目的时候会遇到要求要导出以docx格式结尾的报告文件,于是我就在思考有没有一个比较好用的第三方类库能解决在word上 ...

  2. Freemarker使用mht制作导出word模板

    Freemarker使用mht制作导出word模板 一.制作word导出模板时,我们使用官方的Office Word编辑样式,编辑好之后,另存为mhtml格式,这样我们就可以看到源代码了.注意:创建w ...

  3. poi导出word模板

    **poi导出word模板段落处理 流程: 1:读取文档:` //获取docx解析对象 XWPFDocument document = new XWPFDocument(POIXMLDocument. ...

  4. java向Word模板中替换书签数据,插入图片,插入复选框,插入Word中表格的行数据,删除表格行数据

    java向Word模板中替换书签数据,插入图片,插入复选框,插入Word中表格的行数据,删除表格行数据 使用插件:spire.doc 创建工具类,上代码: import com.spire.doc.D ...

  5. Springboot 导出word,动态填充表格数据

    背景 本文将给大家带来如何导入数据到word文档中,固定传值和动态制作表格传值等. 依赖: <!-- word导出 --><dependency><groupId> ...

  6. springboot+poi-tl根据模板导出word(含动态表格和图片)

    1.pom配置 <dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</ar ...

  7. SpringBoot使用Freemarker导出word模板(OpenXML)

    1.OpenXML 本文仅限WPS的word,微软的word另存为XML的格式略有不同 word.docx文档另存为xml之后会生成带有OpenXML标签的文档. 1.1.常用标签示意 标签 解释 & ...

  8. Freemarker模板引擎:使用HashMap数据形式,导出word模板

    编写:HorinJsor 文章目录 一.Freemarker是什么? 二.Word模板编写 1.导出为xml格式文档 在这里插入图片描述 2.使用HBuilderX重排格式 3.基本模板语法 三.代码 ...

  9. SpringBoot+EasyPOI word模板导出,含多张图片

    这几天客户提出了新的需求,要求记录要能够导出word,并且里面包含的图片也要导出来,这里借用EasyPOI来进行操作. 参考文章:https://blog.csdn.net/qq_34752942/a ...

最新文章

  1. UI设计培训完之后可以去哪些公司工作
  2. 我对CTO的理解 CTO要有技术魅力
  3. PHP explode() 函数
  4. 小细节大功能!通过缺省页你可以告诉用户这些事
  5. php 使用PDO,防止sql注入 简单说明
  6. 【华为云技术分享】“敏捷+ DevOps”先行,效能提升助推企业升级
  7. mysql5.7主从复制--在线变更复制类型【转】
  8. 选择所在城市html按字母,移动端根据字母定位到指定的城市【原创】
  9. 二级c语言程序设计教程微盘,二级C语言教程.pdf
  10. react-native 0.40.0 环境搭建踩坑全记录
  11. CCKS2020基于本体的金融知识图谱自动化构建技术评测第五名方法总结
  12. hdu 2087 剪花布条 kmp小水
  13. TexLive2018中使用BibTeX管理参考文献
  14. 50G PON将成为未来发展部署的重点
  15. 天眼查app协议逆向分析
  16. CVPPA彩色图片转COCO格式
  17. 贴纸UI效果如何制作,4个做贴纸效果的小技巧
  18. ArcGis将2000国家大地坐标系转WGS84
  19. 第一周-机器学习监督学习-无监督学习
  20. 使用java实现输出图形(三角形、菱形等四个图形)

热门文章

  1. 苹果原生二维码生成与扫描及生成的二维码不清楚的解决方案
  2. 【OP都能理解之】 张量
  3. 【杂七杂八的笔记】2019CVPR论文快读
  4. html—显示照片(方法一)
  5. html nav均匀分布的粘性导航栏
  6. Oracle 基本操作
  7. 电子学会-全国青少年编程等级考试真题Scratch一级(2019年3月)
  8. 《 Socket.IO》 解决 WebSocket 通信
  9. Excel快速入门02
  10. 【SQL Server 还原数据库】:因为数据库正在使用,所以无法获得对数据库的独占访问权