使用poi将pptx文件转为图片详解
目录
项目需求
后端接口实现
1、引入poi依赖
2、代码编写
1、controller
2、service层
测试出现的bug
小结
项目需求
前端需要上传pptx文件,后端保存为图片,并将图片地址保存数据库,最后大屏展示时显示之前上传的pptx的图片。需求看上去是简单的,简单聊一下,不管是使用vue的elementui还是传统的layui都有很好的实现组件,这里我们重点不在前端,所以不去细说,感兴趣的同学可以了解一下。
后端接口实现
1、引入poi依赖
这里我使用的是最新的依赖,大家想要稳定一点可以用4.1.2的版本
<!-- excel解析工具 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-scratchpad</artifactId><version>5.2.0</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.4</version></dependency>
2、代码编写
一般工作中,后端都是提供接口给前端访问的,项目会有一定的分层
1、controller
我们主要用来接受参数,然后把参数带到service层去处理业务逻辑就行
这里我们需要接受的前端参数有2个:
MultipartFile:pptx文件对象
代码示例:
@ResponseBody @RequestMapping("/admin/pheno/material/caseContentPhotoUpload")public ResultJson caseContentPhotoUpload(MultipartFile file, HttpServletRequest request) {return ResultJson.build(pheContentService.caseContentPhotoUpload(file,request));}
2、service层
实际的业务代码编写,代码逻辑是比较简单的,先获取文件的输入流,将文件输入流转化为xmlslideshow()对象,这个就是poi的处理pptx文件的工具包了,在里面循环操作每一张pptx。pptx文件也就是xml文件,所以是用这个处理的,然后就是保存图片了,思路就是建一张画布,将文件画上去,最后保存到对应路径,本地数据库啥的。非常简单。IMAGE_SCALE 是一个常量,我给的是8,最后记得关闭不用的对象,回收一下内存。
public ResultService caseContentPhotoUpload(MultipartFile file, HttpServletRequest request) {String serverPath=request.getSession().getServletContext().getRealPath("/");ArrayList<Object> outPathUrlList = new ArrayList<>();InputStream is = null;XMLSlideShow ppt = null;try {is = file.getInputStream();ppt =new XMLSlideShow(is);Dimension pgSize = ppt.getPageSize();for (XSLFSlide slide : ppt.getSlides()) {for(XSLFShape shape : slide.getShapes()){if(shape instanceof XSLFTextShape) {XSLFTextShape tsh = (XSLFTextShape)shape;for(XSLFTextParagraph p : tsh){for(XSLFTextRun r : p){r.setFontFamily("宋体");}}}}String url = toPNG(pgSize.width, pgSize.height, slide,serverPath,hrStaffSession);outPathUrlList.add(url);}} catch (IOException e) {log.debug("ppt转换图片失败,{}"+ e.getMessage());throw new RuntimeException("ppt转换图片失败" + e.getMessage());} finally {try {if (is != null) {is.close();}} catch (IOException e) {e.printStackTrace();}try {if (ppt != null) {ppt.close();}} catch (IOException e) {e.printStackTrace();}}return ResultService.buildSuccess(outPathUrlList);}
protected String toPNG(int pgWidth, int pgHeight, XSLFSlide slide, String serverPath, HrStaffSession hrStaffSession) throws IOException {int imageWidth = (int) Math.floor(IMAGE_SCALE * pgWidth);int imageHeight = (int) Math.floor(IMAGE_SCALE * pgHeight);ResultService resultService =null;BufferedImage img = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);Graphics2D graphics = img.createGraphics();graphics.setPaint(Color.white);graphics.fill(new Rectangle2D.Float(0, 0, pgWidth, pgHeight));graphics.scale(IMAGE_SCALE, IMAGE_SCALE);slide.draw(graphics);ByteArrayOutputStream bos = new ByteArrayOutputStream();try {bos = new ByteArrayOutputStream();ImageIO.write(img, "png", bos);InputStream input = new ByteArrayInputStream(bos.toByteArray());MultipartFile multipartFile = getMultipartFile(input,"ppt图片.png");input.close();resultService = fileService.fileUpload(multipartFile, serverPath, hrStaffSession);} finally {bos.close();}SystemFileVO systemFileVO=(SystemFileVO)resultService.getObject();return systemFileVO.getThumbPath();}
测试出现的bug
不知道是poi对于pptx做的兼容不好还是啥原因,总之有很多的问题
1、文字问题,pptx使用的都是微软雅黑,但是转为图片时,文字会有溢出和下坠的变化,
所以我从4.1.2的包切到了新版本的5.2.0,解决了文字的溢出问题,然后我将微软雅黑统一设置成宋体,在window上是解决了,但是在linux上展现效果又有一定的差异,总的来说是解决了。
2、段落的首行缩进混乱,设置了首行缩进,但是缩进去了一行的最后面
最后只能不要这个样式,去手动添加空格
3、一些图标无法读取,当图标是组合式也就是拼接的时候,会出现读取不了的情况,也只能在写pptx的时候规避一下
4、在不同操作系统上展现效果有细微区别,测试也比较麻烦
。。。
小结
感觉在技术的选取上应该再参考一下,是否poi是这个需求最好的处理对象,是不是还有更好的处理方式。
相关文章:

使用poi将pptx文件转为图片详解
目录 项目需求 后端接口实现 1、引入poi依赖 2、代码编写 1、controller 2、service层 测试出现的bug 小结 项目需求 前端需要上传pptx文件,后端保存为图片,并将图片地址保存数据库,最后大屏展示时显示之前上传的pptx的图片。需求看上…...

【微服务】springboot整合skywalking使用详解
目录 一、前言 二、SkyWalking介绍 2.1 SkyWalking是什么 2.2 SkyWalking核心功能 2.3 SkyWalking整体架构 2.4 SkyWalking主要工作流程 三、为什么选择SkyWalking 3.1 业务背景 3.2 常见监控工具对比 3.3 为什么选择SkyWalking 3.3.1 代码侵入性极低 3.3.2 功能丰…...

electron——查看electron的版本(代码片段)
electron——查看electron的版本(代码片段)1.使用命令行: npm ls electron 操作如下: 2.在软件内使用代码,如下: console.log(process) console.log(process.versions.electron) process 里包含很多信息: process详…...

【Electron】富文本编辑器之文本粘贴
由于这个问题导致,从其他地方复制来的内容 粘贴发送之后都会多一个 换行 在发送的时候如果直接,发送innerHTML 就 可以解决 Electron h5 Andriod 都没问题,但是 公司的 IOS 端 不支持,且不提供支持(做不了。ÿ…...

【哈希数组】697. 数组的度
697. 数组的度 解题思路 首先创建一个IndexMap 键表示元素 值表示一个列表List list存储该元素在数组的所有索引之后再次创建一个map1 针对上面的List 键表示列表的长度 值表示索引的差值遍历indexmap 将所有的list的长度 和 索引的差值存储遍历map1 找到最大的key 那么这个Ke…...
GO语言工具函数库--Lancet
支持300常用功能的开源GO语言工具函数库–Lancet lancet(柳叶刀)是一个全面、高效、可复用的go语言工具函数库。lancet受到了java apache common包和lodash.js的启发。 特性 全面、高效、可复用300常用go工具函数,支持string、slice、dateti…...

25、商城系统(七):商城项目基础功能pom.xml(重要),mybatis分页插件
截止这一章,我们就不把重心放在前端,后台的基础代码,因为后面都是业务层面的crud。 前端直接替换这两个文件夹即可,后台代码也直接复制: 一、重新更新一下所有的pom.xml 这个地方我踩了好多坑,最后得到一个完整的pom.xml,建议大家直接用我的pom.xml替换即可。 1.comm…...

【Docker-Dev】Mac M2 搭建docker mysql
Mac M2 搭建Mysql 1、前言2、前置说明-Docker的代理访问3、前置说明-Mysql的镜像访问3.1、提取信息3.1.1、开启Mysql的实例3.1.2、Dokcer连接Mysql3.1.3、官方简易版的docker-compose3.1.4、如何登录mysql bash3.1.5、自定义my.cnf文件3.1.6、如何知道其他自定义配置项 4、M2安…...

idea中终端Terminal页面输入命令git log后如何退出
1、idea中Terminal输入命令git log后如何退出? 2、解决 输入q键会自动退出git log命令...

程序员必备IDEA插件,什么是是IDE?
IDEA是一款功能强大的集成开发环境(IDE)插件,它可以帮助开发人员更加高效地编写、调试和部署软件应用程序。 我们在编写完接口代码后需要进行接口调试等操作,一般需要打开额外的调试工具。今天就给大家介绍一款IDEA插件ÿ…...

SkyWalking UI 修改发布Nginx
文章目录 SkyWalking UI修改图标修改路由发布到Nginx添加认证修改路由模式vite.config.ts添加baseNginx配置 SkyWalking UI skywalking-booster-ui下载地址 修改图标 替换 logo.svg 修改路由 router - data - index.ts 发布到Nginx 添加认证 # 安装 yum install -y h…...

移动硬盘打不开怎么办?没有比这更好的办法了
移动硬盘打不开是常见故障,可能的原因有很多,例如硬盘驱动器故障、文件系统损坏、分区表错误等。本文将详细分析这些原因,并提供相应的解决方法,帮助您解决移动硬盘打不开的问题。 当移动硬盘打不开时,为了保留其中的文…...

[场景实现]:多选框与树形结构递归
一、场景描述 实现一个分配权限的页面,最左侧是大的权限模块的名称,左右侧是控制其是否勾选的多选框。中间部分是一级权限模块下的子权限名称及多选框。 请求此权限模块数据的接口返回的是树形结构 对象数组。 主要属性为menuName表示权限名࿰…...

从0到1浅析Redis服务器反弹Shell那些事
文章目录 前言Redis服务1.1 特点与应用1.2 安装与使用1.3 语法和配置1.4 未授权访问 反弹Shell2.1 Web服务写入Webshell2.2 Linux定时任务反弹shell2.3 /etc/profile.d->反弹shell2.4 写入ssh公钥登录服务器2.5 利用Redis主从复制RCE2.6 SSRF漏洞组合拳->RCE 总结 前言 …...
JavaScript中alert、confrim、prompt的使用及区别【精选】
Hi i,m JinXiang ⭐ 前言 ⭐ 本篇文章主要介绍JavaScript中alert、confrim、prompt的区别及使用以及部分理论知识 🍉欢迎点赞 👍 收藏 ⭐留言评论 📝私信必回哟😁 🍉博主收将持续更新学习记录获,友友们有任…...
Docker Compose容器编排实战
介绍 Docker Compose 是 Docker 官方提供的一种工具,用于定义和运行多个 Docker 容器的应用。它使用简单的 YAML 文件(通常称为 docker-compose.yml)来配置应用的服务,并使用单个命令即可创建、启动和停止整个应用。 官方文档&am…...

科技创新实验室数据管理优选:高效企业网盘推荐
科技创新实验室建设是国家加强科技创新基本能力建设的重要措施,企业网盘等高效办公工具的应用是保证科技创新实验室正常运行、提高科研项目团队合作效率的重要手段。 本文将介绍企业网盘Zoho WorkDrive提供的解决方案: 行业痛点1:分散的数据…...
记录一次云服务器使用docker搭建kafka的过程
创建网络 一定要将zookeeper注册中心与kafka建在一个network中,不然在springboot 集成 kakfa的demo测试代码中进行消息发送时会超时,报错: E x c e p t i o n t h r o w n w h e n s e n d i n g a m e s s a g e w i t h k e y ‘ n u l l…...
微信小程序与vue区别
微信小程序和Vue是两个完全不同的东西,虽然它们都是前端技术,但是有以下几点区别: 技术栈不同: 微信小程序使用WXML、WXSS和JavaScript进行开发,而Vue使用HTML、CSS和JavaScript进行开发。微信小程序是一种基于微信平台…...

GIT提交、回滚等基本操作记录
1、add文件时warning: LF will be replaced by CRLF in .idea/workspace.xml. 原因:windows中的换行符为 CRLF, 而在Linux下的换行符为LF,所以在执行add . 时会出现以下提示 解决:git config core.autocrlf false 2、GIT命令&…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行
项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战,克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案
一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...
在Spring Boot中集成RabbitMQ的完整指南
前言 在现代微服务架构中,消息队列(Message Queue)是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件,支持多种消息协议,具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...

简单聊下阿里云DNS劫持事件
阿里云域名被DNS劫持事件 事件总结 根据ICANN规则,域名注册商(Verisign)认定aliyuncs.com域名下的部分网站被用于非法活动(如传播恶意软件);顶级域名DNS服务器将aliyuncs.com域名的DNS记录统一解析到shado…...

多模态学习路线(2)——DL基础系列
目录 前言 一、归一化 1. Layer Normalization (LN) 2. Batch Normalization (BN) 3. Instance Normalization (IN) 4. Group Normalization (GN) 5. Root Mean Square Normalization(RMSNorm) 二、激活函数 1. Sigmoid激活函数(二分类&…...