当前位置: 首页 > news >正文

JAVA实现向Word模板中插入Base64图片和数据信息

目录

    • 需求
    • 一、准备模板文件
    • 二、引入Poi-tl、Apache POI依赖
    • 三、创建实体类(用于保存向Word中写入的数据)
    • 四、实现Service接口
    • 五、Controller层实现

需求

在服务端提前准备好Word模板文件,并在用户请求接口时服务端动态获取图片。数据等信息插入到模板当中,然后返回包含数据信息的Word文件流。

一、准备模板文件

在需要插入图片的地方使用:{{@参数名}},文本信息使用:{{参数名}},进行占位,占位格式将会被保留,经过处理后格式不变

在这里插入图片描述

将准备好的模板文件放在resources目录下

blog.csdnimg.cn/direct/6d1474091083427483e11ea71e25ef51.png)

二、引入Poi-tl、Apache POI依赖

poi-tl(poi template language)是Word模板引擎,基于Apache POI,提供更友好的API,使用起来更加简单
版本对应关系参考Poi-tl官网

<!--    替换自己使用的版本    -->
<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.1.*</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.1.*</version>
</dependency>
<!--    Word模板引擎    -->
<dependency><groupId>com.deepoove</groupId><artifactId>poi-tl</artifactId><version>1.7.*</version>
</dependency>

三、创建实体类(用于保存向Word中写入的数据)

参数名必须同Word模板中的参数名称保持一致

import com.deepoove.poi.data.PictureRenderData;@Data
public class DownloadDate {//图片使用PictureRenderData类型private PictureRenderData image;private String name;private String a;private String b;private String c;private String d;private String e;private String f;private String g;private String h;private String i;
}

四、实现Service接口

public interface DownloadService {void download(HttpServletResponse response, DownloadDTO downloadDTO) throws IOException;
}

@Service
@Slf4j
public class DownloadServiceImpl implements DownloadService {@Resource//远程调用服务private FeignService feignService;@Overridepublic void download(HttpServletResponse response, DownloadDTO downloadDTO) throws IOException {BufferedImage、字节数组),Base64可以转字节数组后使用//通过调用其它接口获取待写入的数据信息WordData wordData = feignService.getData(downloadDTO);/** * 图片可以是多种格式------------------------* 图片路径:PictureRenderData(int width, int height, String path)* File:PictureRenderData(int width, int height, File picture)* InputStream:PictureRenderData(int width, int height, String format, InputStream input)* BufferedImage:PictureRenderData(int width, int height, String format, BufferedImage image)* 字节数组:PictureRenderData(int width, int height, String format, byte[] data)* Base64可以转字节数组后使用*///以Base64为例,先获取图片的Base64编码(wordData.getImg是原始图片Base64数据)String base64ImageData = wordData.getImg.substring(data.indexOf(",") + 1);//获取图片类型String format = getBase64Type(base64ImageData);// 将base64数据转为字节数组byte[] imageBytes = Base64.getDecoder().decode(base64ImageData);// 将字节数组包装成PictureRenderDataPictureRenderData pictureRenderData = new PictureRenderData(690,530,format,imageBytes);//待写入Word的数据DownloadDate downloadDate = new DownloadDate();//图片信息downloadDate.setImage(pictureRenderData);//其它信息downloadDate.setName(wordData.getName());//...XWPFTemplate template = null;BufferedOutputStream bufferedOutputStream = null;ServletOutputStream outputStream = null;try {/** * 该方法会导致在部分环境中资源找不到的情况,不推荐使用*///获得resource路径+模板路径//String path = Objects.requireNonNull(Thread.currentThread().getContextClassLoader().getResource("")).getPath() + "word/template.docx";// 读取Word模板//FileInputStream templateInputStream = new FileInputStream(path);// 模板绑定数据//template = XWPFTemplate.compile(templateInputStream).render(imageDownloadDate);// 从资源中加载Word模板try (InputStream templateInputStream = getClass().getClassLoader().getResourceAsStream("word/template.docx")) {if (templateInputStream != null) {// 模板绑定数据template = XWPFTemplate.compile(templateInputStream).render(imageDownloadDate);} else {// 处理模板资源未找到的情况log.error("Word模板资源未找到");response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);return;}}//文件名String encodedFileName = URLEncoder.encode(System.currentTimeMillis()+"", "utf-8");//设置响应信息response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName + ".docx");response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");response.setCharacterEncoding("utf-8");outputStream = response.getOutputStream();bufferedOutputStream = new BufferedOutputStream(outputStream);template.write(bufferedOutputStream);//清空流bufferedOutputStream.flush();outputStream.flush();} catch (Exception e) {log.info(e.getMessage());response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);} finally {//关闭资源PoitlIOUtils.closeQuietlyMulti(template, bufferedOutputStream, outputStream);}}//根据base64编码获取图片格式信息private String getBase64Type(String base64) {byte[] b = Base64.getDecoder().decode(base64);String type = ".png";if (0x424D == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {type = ".bmp";} else if (0x8950 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {type = ".png";} else if (0xFFD8 == ((b[0] & 0xff) << 8 | (b[1] & 0xff))) {type = ".jpg";} else if (0x49492A00 == ((b[0] & 0xff) << 24 | (b[1] & 0xff) << 16 | (b[2] & 0xff) << 8 | (b[3] & 0xff))) {type = ".tif";}return type;}}

五、Controller层实现

@RestController
@RequestMapping("/test")
@Api(tags = "获取商品图片")
public class GetImageController {@ResourceDownloadService downloadService;@PostMapping("/download")@ApiOperation(value = "下载Word")void download(HttpServletResponse response,@RequestBody DownloadDTO downloadDTO) throws IOException {//鉴权或其它处理//....downloadService.download(response,downloadDTO);}}

相关文章:

JAVA实现向Word模板中插入Base64图片和数据信息

目录 需求一、准备模板文件二、引入Poi-tl、Apache POI依赖三、创建实体类&#xff08;用于保存向Word中写入的数据&#xff09;四、实现Service接口五、Controller层实现 需求 在服务端提前准备好Word模板文件&#xff0c;并在用户请求接口时服务端动态获取图片。数据等信息插…...

深入浅出关于go web的请求路由

文章目录 前言一、是否一定要用框架来使用路由&#xff1f;二、httprouter2.1 httprouter介绍2.2 httprouter原理2.3 路由冲突情况 三、gin中的路由四、hertz中的路由总结 前言 最近重新接触Go语言以及对应框架&#xff0c;想借此机会深入下对应部分。 并分享一下最近学的过程…...

HarmonyOS—开发环境诊断的功能

为了大家开发应用/服务的良好体验&#xff0c;DevEco Studio提供了开发环境诊断的功能&#xff0c;帮助大家识别开发环境是否完备。可以在欢迎界面单击Help > Diagnose Development Environment进行诊断。如果已经打开了工程开发界面&#xff0c;也可以在菜单栏单击Help >…...

Golang个人web框架开发-学习流程

Golang-个人web框架 github仓库创建github仓库 web框架学习开发周期第一阶段--了解第一阶段思考小结 第二阶段第三阶段 github仓库 github地址&#xff1a;ameamezhou/golang-web-frame 后续还将继续学习更新 创建github仓库 设置免密登录 ssh-keygen 一路回车就OK 上面有告…...

java面试题(23):Spring Bean如何保证并发安全

1 问题分析 我们知道默认情况下&#xff0c;Spring中的Bean是单例的&#xff0c;所以在多线程并发访问的时候&#xff0c;有可能会出现线程安全问题。 2 解决方案 有几个方面的解决思路&#xff1a; 我们可以设置Bean的作用域设置为原型&#xff08;prototype&#xff09;&a…...

HarmonyOS【应用服务开发】在模块中添加Ability

Ability是应用/服务所具备的能力的抽象&#xff0c;一个Module可以包含一个或多个Ability。应用/服务先后提供了两种应用模型&#xff1a; FA&#xff08;Feature Ability&#xff09;模型&#xff1a; API 7开始支持的模型&#xff0c;已经不再主推。Stage模型&#xff1a;AP…...

根据屏幕尺寸设置html根字号fontSize大小并刷新

<script> // rem等比适配配置文件 // 基准大小 const baseSize 16 // 设置 rem 函数 function setRem() {// 当前页面宽度相对于 1920宽的缩放比例&#xff0c;可根据自己需要修改。const scale document.documentElement.clientWidth / 1920console.log(document.docu…...

Flutter 中的 InteractiveViewer:轻松实现交互性

在Flutter中&#xff0c;为了创建具有交互性的用户界面&#xff0c;我们通常需要使用各种手势检测和动画。然而&#xff0c;Flutter提供了一个强大而简便的小部件&#xff0c;即InteractiveViewer&#xff0c;它可以帮助我们轻松实现拖动、缩放和其他手势交互效果。本文将介绍I…...

UE4 添加按键输入事件 并在蓝图中使用按键输入节点

绑定按键 选择Edit/ProjectSettings/Engine/Input 在bindings中可以选择添加ActionMappings或则AxisMappings ActionMappings:按键事件&#xff0c;有按下和抬起两个事件&#xff0c;需要分别用两个键触发AxisMappings:输入事件&#xff0c;返回值为float&#xff0c;对于键盘…...

Go 语言命名规范:清晰、简洁、一致

Go 语言命名规范&#xff1a;清晰、简洁、一致 Go 语言是一门注重简洁和一致性的编程语言&#xff0c;良好的命名规范是代码可读性和维护性的关键因素之一。在本篇博客中&#xff0c;我们将深入探讨 Go 语言的命名规范&#xff0c;包括标识符、包名、常量、变量、函数等各个方…...

代码随想录训练营第三十期|第十天|栈与队列part01|理论基础● 232.用栈实现队列● 225. 用队列实现栈

232. 用栈实现队列 - 力扣&#xff08;LeetCode&#xff09; class MyQueue {Stack<Integer> in;Stack<Integer> out;public MyQueue() {in new Stack<>();out new Stack<>();}public void push(int x) {in.push(x);}public int pop() {move();retu…...

Backtrader 文档学习-Indicators混合时间框架

Backtrader 文档学习-Indicators混合时间周期 1.不同时间周期 如果数据源在Cerebro引擎中具有不同的时间范围和不同的长度&#xff0c;指示器将会终止。 比如&#xff1a;data0是日线&#xff0c;data1是月线 。 pivotpoint btind.PivotPoint(self.data1) sellsignal self…...

网络攻击与检测防御:维护数字安全的关键挑战

随着数字化时代的深入&#xff0c;网络攻击已成为企业和个人面临的严峻挑战之一。本文将深入探讨不同类型的网络攻击&#xff0c;以及有效的检测和防御策略&#xff0c;以确保网络系统的安全性和稳定性。 1. 常见网络攻击类型&#xff1a; DDoS 攻击&#xff1a;分布式拒绝服…...

使用 Vector 在 Kubernetes 中收集日志

多年来&#xff0c;我们一直在使用 Vector 在我们的 Kubernetes 平台中收集日志&#xff0c;并成功地将其应用于生产中以满足各种客户的需求&#xff0c;并且非常享受这种体验。因此&#xff0c;我想与更大的社区分享它&#xff0c;以便更多的 K8s 运营商可以看到潜力并考虑他们…...

ardupilot开发 --- 固件定制(OEM) 篇

0. 前言 固件功能定制OEM Customization&#xff1a; 原厂设备制造商OEM&#xff08;Original Equipment Manufacturer&#xff09;、代工功能勾选参数预设固件名称自定义 1. 基于某个飞控硬件来定制自己的飞控产品 可以自定义的包括&#xff1a;固件名称、预设参数、lua脚本…...

爬虫代理IP在电商行业的应用

随着互联网的快速发展&#xff0c;电商行业已经成为人们购物的主要渠道之一。在电商行业中&#xff0c;数据分析和挖掘至关重要。爬虫代理IP作为一种能够提供大量模拟请求和收集数据的工具&#xff0c;被广泛应用于电商行业。下面介绍爬虫代理IP在电商行业中的应用。 1、保护隐…...

Vue配置语法检查及关闭语法检查的说明

1. 第一种方式&#xff1a;//eslint-disable-next-line 2. 第二种方式&#xff1a;/*eslint-disable*/ 3. 第三种方式&#xff1a;vue.config.js中配置 &#xff0c;具体配置如下&#xff1a; const { defineConfig } require(vue/cli-service)module.exports defineConfig…...

【Linux】yum

个人主页 &#xff1a; zxctsclrjjjcph 文章封面来自&#xff1a;艺术家–贤海林 如有转载请先通知 yum 1. 什么是yum&#xff1f;2. Linux系统(Centos)的生态3. yum的相关操作4. yum的本地配置5. 如何安装软件 1. 什么是yum&#xff1f; yum是一个软件下载安装的一个客户端&a…...

安装sftpgo

1.下载安装包;选择自己需要的cpu架构和操作系统的版本 https://github.com/drakkan/sftpgo/releases/tag/v2.5.6推荐使用版本下载地址 https://github.com/drakkan/sftpgo/releases/download/v2.5.6/sftpgo_v2.5.6_linux_x86_64.tar.xz2.解压文件到某个文件夹,根据需要修改配…...

JS-元素尺寸与位置

通过js的方式&#xff0c;得到元素在页面中的位置 获取宽高 元素.offsetWidth 元素.offsetHeight 1&#xff09;获取元素的自身宽高、包括元素自身设置的宽高paddingborder 2&#xff09;获取出来的是数值&#xff0c;方便计算 3&#xff09;注意&#xff1a;获取的是可视…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...