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);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/634411.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代理IP是什么,代理IP的工作原理是怎么样的?

数字时代&#xff0c;随着数据采集的应用&#xff0c;代理IP也受到越来越多人的关注。但是&#xff0c;很多人对代理IP的具体概念及其工作原理并不是很了解。今天我们就来针对代理IP的相关知识做一个简单的探讨&#xff0c;说说代理IP是什么&#xff0c;它的工作原理又是什么&a…

redis未授权访问全漏洞复现

redis未授权访问全漏洞复现 Redis 有关的漏洞具有明显的时间分段性&#xff0c;在15年11月之前&#xff0c;主要是未授权导致的数据泄露&#xff0c;获得一些账号密码。另外还可以 DoS&#xff08;参考&#xff1a;Sangfor VMP redis unauthorized access vulnerability&#…

VUE--组件通信(非父子)

一、非父子通信 --- event bus 事件总线 作用&#xff1a;非父子组件之间进行简易的消息传递 步骤&#xff1a; 1、创建一个都能访问到的事件总线&#xff08;空vue实例&#xff09;--- utils/EventBus.js import Vue from vue export default new Vue({}) 2、 接收方&…

mysql数据库:迁移数据目录至另一台服务器步骤

一、概述 最近由于项目需要&#xff0c;我们需要进行数据库服务器的更换和迁移工作。迁移计划和步骤如下&#xff1a; 1、首先&#xff0c;在新的数据库服务器上进行环境的搭建和配置&#xff0c;确保数据库版本、配置等一致。 2、然后&#xff0c;将备份的数据库数据导入到…

SpringBoot整合SSE

目录 1.SseController2. SseServiceSseServiceSseServiceImpl 3.SendMessageTask4.将定时任务加入启动类5.参考资料 1.SseController Slf4j RestController RequestMapping("sse") public class SseController {Autowiredprivate SseService sseService;RequestMappi…

【算法练习】leetcode算法题合集之二分查找篇

二分查找 LeetCode69.x的平方根 LeetCode69.x的平方根 只要小于等于就可以满足条件了。 class Solution {public int mySqrt(int x) {int left 0, right x;int ans -1;while (left < right) {int mid (right - left) / 2 left;if ((long) mid * mid < x) {ans mi…

为 OpenCV 编写文档(二)

常用命令 这里通过简短的示例描述了最常用的 doxygen 命令。有关可用命令的完整列表和详细说明&#xff0c;请访问命令参考。 基本命令 brief - 带有简要实体描述的段落 param - 函数参数的描述。 多个相邻语句合并到一个列表中。如果在实际函数签名中找不到具有此名称的参数…

2024潮乎新年盲盒H5版本可易支付对接

前端三十行和三十一行改成你域名 后台.env文件修改数据库 下载地址&#xff1a;YISHEN源码网

驾驭车联网的力量:深入车联网网络架构

车联网&#xff0c;作为移动互联网之后的新风口&#xff0c;以网联思想重新定义汽车&#xff0c;将其从简单的出行工具演化为个人的第二空间。车联网涵盖智能座舱和自动驾驶两大方向&#xff0c;构建在网联基础上&#xff0c;犀思云多年深度赋能汽车行业&#xff0c;本文将从车…

Qt通用属性工具:随心定义,随时可见(三)

传送门: 《Qt通用属性工具:随心定义,随时可见(一)》 《Qt通用属性工具:随心定义,随时可见(二)》 《Qt通用属性工具:随心定义,随时可见(三)》 一、效果展示 本文将展示的是一个源于Qt但是却有些年头的Qt属性浏览工具。支持交互式编辑和查阅对象属性。 这可不就是妥…

LeetCode、162. 寻找峰值【中等,最大值、二分】

文章目录 前言LeetCode、162. 寻找峰值【中等&#xff0c;最大值、二分】题目及类型思路及代码思路1&#xff1a;二分思路2&#xff1a;寻找最大值 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿…

Filter过滤器、使用场景、使用办法、创建和配置等

这里写目录标题 过滤器应用场景自动登录统一设置编码格式访问权限控制敏感字符过滤 Filter使用Filter的创建和配置 过滤器 过滤器实际上就是对 web资源进行拦截&#xff0c;做一些处理后再交给下一个过滤器或 servlet处理通常都是用来拦截request进行处理的&#xff0c;也可以…

2023年全球软件质量效能大会(QECon深圳站):核心内容与学习收获(附大会核心PPT下载)

随着科技的快速发展&#xff0c;软件行业面临着越来越多的挑战和机遇。为了更好地应对这些挑战&#xff0c;不断提升软件的质量和效能&#xff0c;大会将汇聚全球的软件开发者、架构师和项目经理&#xff0c;共同探讨和分享关于软件质量保证、测试、性能优化、用户体验设计、人…

使用nginx搭建网页

一、实验要求 网站需求&#xff1a; 1.基于域名www.openlab.com可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于www.openlab.com/student 网站访问学生信息&#xff0c;www.openlab.com…

【GAMES101】Lecture 08 着色频率

目录 着色频率 Flat shading&#xff08;平面着色&#xff09; Gouraud shading&#xff08;顶点着色&#xff09; Phong shading&#xff08;像素着色&#xff09; 如何计算法线 着色频率 大家可以看到下面这三个球是看起来不一样的是吧&#xff0c;但是其实这三个球用的…

Qt/C++自定义界面大全/20套精美皮肤/26套精美UI界面/一键换肤/自定义颜色/各种导航界面

一、前言 这个系列对应自定义控件大全&#xff0c;一个专注于控件的编写&#xff0c;一个专注于UI界面的编写&#xff0c;程序员有两大软肋&#xff0c;一个是忌讳别人说自己的程序很烂很多bug&#xff0c;一个就是不擅长UI&#xff0c;基本上配色就直接rgb&#xff0c;对于第…

c++:基于c语言基础上的语法不同(1)

前言&#xff1a;此篇文章适合学完c语言基础概念的同学&#xff0c;是帮助c向c语言的同学快速掌握基本语法。 基础格式 #include<iostream>using namespace std; int main() {system("pause");return 0; } 输入&#xff1a; cin>>a;//a是输入内容 输出…

vue基于Spring Boot的中医在线学习课程购买服务管理系统

SpinrgBoot的主要优点有&#xff1a; 1、为所有spring开发提供了一个更快、更广泛的入门体验&#xff1b; 2、零配置&#xff1b; 3、集成了大量常用的第三方库的配置&#xff1b; 4、提供准备好的特性。当今&#xff0c;nodejs领域的开发者机会都在使用SpinrgBoot,在开发领域逐…

【探索C++容器:vector的使用和模拟实现】

【本节目标】 1.vector的介绍及使用 2.vector深度剖析及模拟实现 1.vector的介绍及使用 1.1 vector的介绍 vertor文档介绍 1. vector是表示可变大小数组的序列容器。2. 就像数组一样&#xff0c;vector也采用连续存储空间来存储元素。也就是意味着可以采用下标对vector的元…

轻松一刻 浅休息下哈

yum -y install epel-release yum install -y linux_logo cal 此命令以日历表的方式显示日期 curl http://wttr.in 此网站进行在屏幕上面显示天气情况