JAVA读取从WPS在Excel中嵌入的图片资源

读取从WPS在Excel中嵌入的图片资源


引言

许多数据文件中可能包含嵌入式图片,这些图片对于数据分析和可视化非常重要。然而,从 WPS 在 Excel 中读取这些图片可能会有一些技术挑战。在本文中,我将展示如何从 WPS Excel 文件中读取嵌入的图片,并提供代码示例。

提取图片资源的方法

以下是用于从 WPS Excel 文件中读取图片资源的方法。我们使用了 Apache POI 库来处理 Excel 文件,并使用了 cn.hutool.json 库来处理 XML 数据。这些库可以帮助我们解析 Excel 文件中的嵌入式图片。
在这里插入图片描述

主函数

首先,我们定义了主函数 main,用于测试图片提取功能:

public static void main(String[] args) {PicturesUtils picturesUtils = new PicturesUtils();byte[] fileData = picturesUtils.getFileStream(new File("你的文件路径"));Map<String, XSSFPictureData> pictures = picturesUtils.getPictures(fileData);pictures.forEach((id, xssfPictureData) -> {System.out.println("id:" + id);String fileName = xssfPictureData.getPackagePart().getPartName().getName();System.out.println("fileName:" + fileName);File file = new File("D:\\" + fileName);File dir = file.getParentFile();dir.mkdirs();try {Files.write(Path.of(file.getPath()), xssfPictureData.getData());} catch (IOException e) {e.printStackTrace();}});
}

在这个函数中,我们创建了一个 PicturesUtils 实例,并从文件路径中获取文件数据。然后,我们调用 getPictures 方法来提取图片资源,并遍历结果将图片写入本地文件。

获取浮动图片

接下来,我们展示了如何从 Excel 文件中获取浮动图片:

public static Map<String, XSSFPictureData> getFloatingPictures(XSSFSheet xssfSheet) {Map<String, XSSFPictureData> mapFloatingPictures = new HashMap<>();XSSFDrawing drawingPatriarch = xssfSheet.getDrawingPatriarch();if (drawingPatriarch != null) {List<XSSFShape> shapes = drawingPatriarch.getShapes();for (XSSFShape shape : shapes) {if (shape instanceof XSSFPicture picture) {XSSFClientAnchor anchor = (XSSFClientAnchor) picture.getAnchor();XSSFPictureData pictureData = picture.getPictureData();String key = anchor.getRow1() + "-" + anchor.getCol1();mapFloatingPictures.put(key, pictureData);}}}return mapFloatingPictures;
}

该方法接收一个 XSSFSheet 对象,并返回一个包含浮动图片的映射。它遍历工作表中的所有形状,并将图片数据存储在映射中。

处理图片数据

最后,我们展示了如何处理 Excel 文件中的图片数据,包括嵌入式图片和浮动式图片:

public Map<String, XSSFPictureData> getPictures(byte[] data) {try {Map<String, String> mapConfig = processZipEntries(new ByteArrayInputStream(data));Map<String, XSSFPictureData> mapPictures = processPictures(new ByteArrayInputStream(data), mapConfig);Iterator<Sheet> sheetIterator = WorkbookFactory.create(new ByteArrayInputStream(data)).sheetIterator();while (sheetIterator.hasNext()) {mapPictures.putAll(getFloatingPictures((XSSFSheet) sheetIterator.next()));}return mapPictures;} catch (IOException e) {return new HashedMap<>();}
}

在该方法中,我们使用 processZipEntries 和 processPictures 方法来处理 Zip 文件中的条目和图片数据。然后,通过遍历 Excel 文件中的所有工作表,获取浮动图片。

完整代码示例

实际在程序中读取的内容为=DISPIMG(“ID_03BC802DDAB24510A9883DB157EAC0F8”,1)公式
将公式中的id提取出来ID_03BC802DDAB24510A9883DB157EAC0F8,最后就可以使用下面方法拿到当前id获取到的图片资源

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.XML;
import com.szjyrs.business.exhibition.product.domain.vo.ProductPlusImportLogVo;
import com.szjyrs.common.core.dev.method.MethodStatus;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.web.multipart.MultipartFile;import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;/*** @author bianhl* @version 1.0* @description 获取图片资源* @date 2024年4月28日08:44:42*/
@Slf4j
public class PicturesUtils {public static void main(String[] args) {PicturesUtils picturesUtils = new PicturesUtils();byte[] fileData = picturesUtils.getFileStream(new File("你的文件路径"));Map<String, XSSFPictureData> pictures = picturesUtils.getPictures(fileData);pictures.forEach((id, xssfPictureData) -> {System.out.println("id:" + id);String fileName = xssfPictureData.getPackagePart().getPartName().getName();System.out.println("fileName:" + fileName);File file = new File("D:\\" + fileName);File dir = file.getParentFile();dir.mkdirs();try {Files.write(Path.of(file.getPath()), xssfPictureData.getData());} catch (IOException e) {e.printStackTrace();}});}/*** 获取浮动图片,以 map 形式返回,键为行列格式 x-y。** @param xssfSheet WPS 工作表* @return 浮动图片的 map*/public static Map<String, XSSFPictureData> getFloatingPictures(XSSFSheet xssfSheet) {Map<String, XSSFPictureData> mapFloatingPictures = new HashMap<>();XSSFDrawing drawingPatriarch = xssfSheet.getDrawingPatriarch();if (drawingPatriarch != null) {List<XSSFShape> shapes = drawingPatriarch.getShapes();for (XSSFShape shape : shapes) {if (shape instanceof XSSFPicture picture) {XSSFClientAnchor anchor = (XSSFClientAnchor) picture.getAnchor();XSSFPictureData pictureData = picture.getPictureData();String key = anchor.getRow1() + "-" + anchor.getCol1();mapFloatingPictures.put(key, pictureData);}}}return mapFloatingPictures;}/*** 处理 WPS 文件中的图片数据,返回图片信息 map。** @param stream    输入流* @param mapConfig 配置映射* @return 图片信息的 map* @throws IOException*/private Map<String, XSSFPictureData> processPictures(ByteArrayInputStream stream, Map<String, String> mapConfig) throws IOException {Map<String, XSSFPictureData> mapPictures = new HashedMap<>();Workbook workbook = WorkbookFactory.create(stream);List<XSSFPictureData> allPictures = (List<XSSFPictureData>) workbook.getAllPictures();for (XSSFPictureData pictureData : allPictures) {PackagePartName partName = pictureData.getPackagePart().getPartName();String uri = partName.getURI().toString();if (mapConfig.containsKey(uri)) {String strId = mapConfig.get(uri);mapPictures.put(strId, pictureData);}}return mapPictures;}/*** 获取 WPS 文档中的图片,包括嵌入式图片和浮动式图片。** @param data 二进制数据* @return 图片信息的 map* @throws IOException*/public Map<String, XSSFPictureData> getPictures(byte[] data) {try {Map<String, String> mapConfig = processZipEntries(new ByteArrayInputStream(data));Map<String, XSSFPictureData> mapPictures = processPictures(new ByteArrayInputStream(data), mapConfig);Iterator<Sheet> sheetIterator = WorkbookFactory.create(new ByteArrayInputStream(data)).sheetIterator();while (sheetIterator.hasNext()) {mapPictures.putAll(getFloatingPictures((XSSFSheet) sheetIterator.next()));}return mapPictures;} catch (IOException e) {return new HashedMap<>();}}/*** 处理 Zip 文件中的条目,更新图片配置信息。** @param stream Zip 输入流* @return 配置信息的 map* @throws IOException*/private Map<String, String> processZipEntries(ByteArrayInputStream stream) throws IOException {Map<String, String> mapConfig = new HashedMap<>();ZipInputStream zipInputStream = new ZipInputStream(stream);ZipEntry zipEntry;while ((zipEntry = zipInputStream.getNextEntry()) != null) {try {final String fileName = zipEntry.getName();if ("xl/cellimages.xml".equals(fileName)) {processCellImages(zipInputStream, mapConfig);} else if ("xl/_rels/cellimages.xml.rels".equals(fileName)) {return processCellImagesRels(zipInputStream, mapConfig);}} finally {zipInputStream.closeEntry();}}return new HashedMap<>();}/*** 处理 Zip 文件中的 cellimages.xml 文件,更新图片配置信息。** @param zipInputStream Zip 输入流* @param mapConfig      配置信息的 map* @throws IOException*/private void processCellImages(ZipInputStream zipInputStream, Map<String, String> mapConfig) throws IOException {String content = IOUtils.toString(zipInputStream, StandardCharsets.UTF_8);JSONObject jsonObject = XML.toJSONObject(content);if (jsonObject != null) {JSONObject cellImages = jsonObject.getJSONObject("etc:cellImages");if (cellImages != null) {JSONArray cellImageArray = cellImages.getJSONArray("etc:cellImage");if (cellImageArray == null) {JSONObject cellImageObj = cellImages.getJSONObject("etc:cellImage");if (cellImageObj != null) {cellImageArray = new JSONArray();cellImageArray.add(cellImageObj);}}if (cellImageArray != null) {processImageItems(cellImageArray, mapConfig);}}}}/*** 处理 cellImageArray 中的图片项,更新图片配置信息。** @param cellImageArray 图片项的 JSONArray* @param mapConfig      配置信息的 map*/private void processImageItems(JSONArray cellImageArray, Map<String, String> mapConfig) {for (int i = 0; i < cellImageArray.size(); i++) {JSONObject imageItem = cellImageArray.getJSONObject(i);if (imageItem != null) {JSONObject pic = imageItem.getJSONObject("xdr:pic");if (pic != null) {processPic(pic, mapConfig);}}}}/*** 处理 pic 中的图片信息,更新图片配置信息。** @param pic       图片的 JSONObject* @param mapConfig 配置信息的 map*/private void processPic(JSONObject pic, Map<String, String> mapConfig) {JSONObject nvPicPr = pic.getJSONObject("xdr:nvPicPr");if (nvPicPr != null) {JSONObject cNvPr = nvPicPr.getJSONObject("xdr:cNvPr");if (cNvPr != null) {String name = cNvPr.getStr("name");if (StringUtils.isNotEmpty(name)) {String strImageEmbed = updateImageEmbed(pic);if (strImageEmbed != null) {mapConfig.put(strImageEmbed, name);}}}}}/*** 获取嵌入式图片的 embed 信息。** @param pic 图片的 JSONObject* @return embed 信息*/private String updateImageEmbed(JSONObject pic) {JSONObject blipFill = pic.getJSONObject("xdr:blipFill");if (blipFill != null) {JSONObject blip = blipFill.getJSONObject("a:blip");if (blip != null) {return blip.getStr("r:embed");}}return null;}/*** 处理 Zip 文件中的 relationship 条目,更新配置信息。** @param zipInputStream Zip 输入流* @param mapConfig      配置信息的 map* @return 配置信息的 map* @throws IOException*/private Map<String, String> processCellImagesRels(ZipInputStream zipInputStream, Map<String, String> mapConfig) throws IOException {String content = IOUtils.toString(zipInputStream, StandardCharsets.UTF_8);JSONObject jsonObject = XML.toJSONObject(content);JSONObject relationships = jsonObject.getJSONObject("Relationships");if (relationships != null) {JSONArray relationshipArray = relationships.getJSONArray("Relationship");if (relationshipArray == null) {JSONObject relationshipObj = relationships.getJSONObject("Relationship");if (relationshipObj != null) {relationshipArray = new JSONArray();relationshipArray.add(relationshipObj);}}if (relationshipArray != null) {return processRelationships(relationshipArray, mapConfig);}}return null;}/*** 处理 relationshipArray 中的关系项,更新配置信息。** @param relationshipArray 关系项的 JSONArray* @param mapConfig         配置信息的 map* @return 配置信息的 map*/private Map<String, String> processRelationships(JSONArray relationshipArray, Map<String, String> mapConfig) {Map<String, String> mapRelationships = new HashedMap<>();for (int i = 0; i < relationshipArray.size(); i++) {JSONObject relaItem = relationshipArray.getJSONObject(i);if (relaItem != null) {String id = relaItem.getStr("Id");String value = "/xl/" + relaItem.getStr("Target");if (mapConfig.containsKey(id)) {String strImageId = mapConfig.get(id);mapRelationships.put(value, strImageId);}}}return mapRelationships;}/*** @param file                   数据文件* @return {@link byte[]}* @description* @author bianhl* @date 2024/4/26 13:52*/private byte[] getFileStream(File file) {try (InputStream inputStream = new FileInputStream(file)) {// 创建 ByteArrayOutputStream 来暂存流数据ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();// 将 inputStream 读取到 byteArrayOutputStream 中byte[] buffer = new byte[1024];int length;while ((length = inputStream.read(buffer)) != -1) {byteArrayOutputStream.write(buffer, 0, length);}// 将 byteArrayOutputStream 的内容获取为字节数组return byteArrayOutputStream.toByteArray();} catch (IOException e) {return null;}}}

输出结果:
在这里插入图片描述
拿到的图片数据
在这里插入图片描述

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

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

相关文章

Jmeter Beanshell 设置全局变量

//获取token import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONArray; import java.util.*; import org.apache.jmeter.util.JMeterUtils; //获取可上机机器 String response prev.getResponseDataAsString(); JSONObject responseObect JSONObjec…

【CANoe示例分析】TCP Chat(CAPL) with TLS encription

1、工程路径 C:\Users\Public\Documents\Vector\CANoe\Sample Configurations 15.3.89\Ethernet\Simulation\TLSSimChat 在CANoe软件上也可以打开此工程:File|Help|Sample Configurations|Ethernet - Simulation of Ethernet ECUs|Basic AUTOSAR Adaptive(SOA) 2、示例目…

秋招后端开发面试题 - JVM底层原理

目录 JVM底层原理前言面试题Java 对象的创建过程&#xff1f;什么是指针碰撞&#xff1f;什么是空闲列表&#xff1f;/ 内存分配的两种方式&#xff1f;JVM 里 new 对象时&#xff0c;堆会发生抢占吗&#xff1f;JVM 是怎么设计来保证线程安全的&#xff1f;/ 内存分配并发问题…

tokio多任务绑定cpu(绑核)

tokio 是 rust 生态中流行的异步运行时框架。在实际生产中我们如果希望 tokio 应用程序与特定的 cpu core 绑定该怎么处理呢&#xff1f; 首先我们先写一段简单的多任务程序。 use tokio; use tokio::runtime; use core_affinity;fn tokio_sample() {let rt runtime::Builde…

网络安全的防护措施有哪些?

1. 安全策略和合规性 2. 物理和网络安全 3. 数据加密 4. 软件和系统更新 5. 访问控制 6. 威胁监测和响应 7. 员工培训和安全意识 8. 备份和灾难恢复 零基础入门学习路线 视频配套资料&国内外网安书籍、文档 网络安全面试题 网络安全的防护措施多种多样&#xff0c…

开源相机管理库Aravis例程学习(五)——camera-api

开源相机管理库Aravis例程学习&#xff08;五&#xff09;——camera-api 简介例程代码函数说明arv_camera_get_regionarv_camera_get_pixel_format_as_stringarv_camera_get_pixel_formatARV_PIXEL_FORMAT_BIT_PER_PIXEL 简介 本文针对官方例程中的&#xff1a;03-camera-api…

甘特图是什么?利用甘特图来优化项目管理流程

在现代项目管理中,图表是一种强大而直观的工具,可以帮助项目经理和团队成员清晰地了解并掌控整个项目进程。其中,甘特图是最常用和最有效的图表之一。 甘特图是一种条形图,可以用来直观地展示项目中各个任务的进度、持续时间和相互关系。它由一个横轴和一个纵轴组成。横轴代表时…

centos 7使用源码编译安装Python 3.12.2(最新版本)

&#xff08;一&#xff09;、说明 在centos 7上&#xff0c;默认安装出来的python是&#xff1a;2.7.5版本 1.查看python版本&#xff1a; python --version 2.通过yum安装出来的&#xff0c;适合当前操作系统的&#xff0c;最新的python版本是&#xff1a;3.6.8 python3…

linux的压缩与备份

一、打包 格式&#xff1a;tar -参数 <打包文件名> <打包的目标> 作用&#xff1a;将文件或者目录打包 重要参数&#xff1a;-f 使用归档文件&#xff0c;一定要加上这个参数 -c 新建打包文件 -x 解包文件 -t 可以不用解包就能查看包文件内容 -v 打包和解包时显…

02.Kafka部署安装

1 Linux 安装 Kafka 1.1 安装前的环境准备 由于 Kafka 是用 Scala 语言开发的&#xff0c;运行在 JVM 上&#xff0c;因此在安装Kafka之前需要先安装JDK。 yum install java-1.8.0-openjdk* -y kafka 依赖 zookeeper&#xff0c;所以需要先安装 zookeeper。 wget https://ar…

MongoDB 使用

一、引用依赖包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId></dependency> 二、 配置文件配置mongodb资料 MongoDB连接信息 spring.data.mongodb.host 192.16…

一款pdf工具

下载链接&#xff1a;点击跳转&#xff1b; 它是一个installer&#xff0c;下好它之后&#xff0c;把网断掉&#xff0c;然后双击它&#xff0c;他会默认安装在C盘&#xff0c;安装时&#xff0c;浏览器可能会有一个弹窗&#xff0c;直接关掉并进入任务管理器杀掉所有smallerp…

deepflow grafana plugin 编译问题解决

修改tsconfig.js 增加"noImplicitAny": false&#xff0c;解决代码类型没有指定&#xff0c;显示Any 错误 To solve the error, explicitly set the parameters type to any, use a more specific type or set noImplicitAny to false in tsconfig.json. https://b…

《面向云计算的零信任体系第1部分:总体架构》行业标准正式发布

中华人民共和国工业和信息化部公告2024年第4号文件正式发布行业标准&#xff1a;YD/T 4598.1-2024《面向云计算的零信任体系 第1部分&#xff1a;总体架构》&#xff08;后简称“总体架构”&#xff09;&#xff0c;并于2024年7月1日正式施行。 该标准由中国信通院牵头&#xf…

pycharm 安装“通义灵码“并测试

过程&#xff1a;“File>setting>Plugins” 提示&#xff1a; 翻译之后&#xff1a; 点击"接受"之后&#xff0c;提示一下图片&#xff0c;点击ok 安装完成&#xff1a; 安装完"通义灵码"之后&#xff0c;需要登陆&#xff0c;登陆后测试 参考…

Python快速入门1数据类型(需要具有编程基础)

数据类型&#xff1a; Python 3.0版本中常见的数据类型有六种&#xff1a; 不可变数据类型可变数据类型Number&#xff08;数字&#xff09;List&#xff08;列表&#xff09;String&#xff08;字符串&#xff09;Dictionary&#xff08;字典&#xff09;Tuple&#xff08;元…

错误(10048): “调用exui内部功能”库命令的参数“参数4”不能接受空数据。怎么解决?

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

Linux基本指令(2)

目录 mv指令&#xff1a; cat&#xff1a; more指令&#xff1a; less指令&#xff1a; head指令&#xff1a; tail指令&#xff1a; mv指令&#xff1a; 说明&#xff1a; mv命令是move的缩写&#xff0c;可以用来移动文件或者文件改名(move(rename)files),是linux系统下…

Pixelmator Pro for Mac:简洁而强大的图像编辑软件

Pixelmator Pro for Mac是一款专为Mac用户设计的图像编辑软件&#xff0c;它集简洁的操作界面与强大的功能于一身&#xff0c;为用户提供了卓越的图像编辑体验。 Pixelmator Pro for Mac v3.5.9中文激活版下载 该软件支持多种文件格式&#xff0c;包括常见的JPEG、PNG、TIFF等&…

高频面试题:解决Spring框架中的循环依赖问题

引言&#xff1a;什么是Spring框架与循环依赖&#xff1f; 在Spring框架中&#xff0c;循环依赖是指两个或多个bean相互依赖对方以完成自己的初始化。这种依赖关系形成了一个闭环&#xff0c;导致无法顺利完成依赖注入。比如&#xff0c;如果Bean A在其构造函数中需要Bean B&a…