从excel中提取嵌入式图片的解决方法

1  发现问题

我的excel中有浮动图片和嵌入式图片,但是openpyxl的_image对象只提取到了浮动图片,通过阅读其源码发现,这是因为openpyxl只解析了drawing文件导致的,所以确定需要自己解析

2  解决思路

1、解析出media资源

2、解析出xml,这可以得到资源的rNvpr-rId-image target的关系

3、从xlrd或openpyxl中得到单元格cNvpr,定位到图片

3  解析xlsx

先把xlsx解压出来,得到的文件如下,其中xl文件夹是我们需要的

我分析了里面的所有文件,发现这两个文件存储了嵌入式图片的关键信息

  • xl/cellimages.xml
  • xl/_rels/cellimages.xml

打开这两个文件看看,到底存储了什么?

3.1  xl/cellimages.xml

有效信息在cellImage对象中

  • cellImage.pic.nvPicPr.cNvPr.name:记录了函数名
  • cellImage.pic.blipFill.blip.embed:记录了rId

记录这个关系,并建立映射关系 { ID_xxx: rId }

3.2  xl/_rels/cellimages.xml

有效信息在Relationship对象中

  • Relationship.id:文件rId
  • Relationship.target:图片地址

建立这个映射关系 { rId: target }

到这一步我们已经可以从函数名定位到图片资源了,剩下一步建立excel单元格和图片的关系,接下来解析excel文件

{ ID_xxx: rId } + { rId: target } = ID_xxx -> target

4  代码实现

接下来简单的代码实现,有问题可以评论区留言,看到会回复

此实现基于openpyxl

from xml.etree.ElementTree import fromstring
from io import BytesIO
from zipfile import ZipFilefrom openpyxl import load_workbook
from openpyxl.packaging.relationship import get_rels_path, get_dependents
from openpyxl.xml.constants import SHEET_DRAWING_NS, REL_NS, IMAGE_NS
from openpyxl.drawing.image import Image, PILImagedef parse_element(element):"""将XML解析为 {ID_XXX: rId}:param element:<etc:cellImage><xdr:pic><xdr:nvPicPr><xdr:cNvPr id="2" name="ID_CBD7CEBC94B44923A5B447F3F21C1995" descr="upload_post_object_v2_167528160"/><xdr:cNvPicPr/></xdr:nvPicPr><xdr:blipFill><a:blip r:embed="rId1"/><a:stretch><a:fillRect/></a:stretch></xdr:blipFill><xdr:spPr><a:xfrm><a:off x="0" y="0"/><a:ext cx="9144000" cy="4796155"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom></xdr:spPr></xdr:pic></etc:cellImage>:return:"""data = {}xdr_namespace = "{%s}" % SHEET_DRAWING_NStargets = level_order_traversal(element, xdr_namespace + "nvPicPr")for target in targets:# 是一个cellimagecNvPr = embed = ""for child in target:if child.tag == xdr_namespace + "nvPicPr":cNvPr = child[0].attrib["name"]elif child.tag == xdr_namespace + "blipFill":_rel_embed = "{%s}embed" % REL_NSembed = child[0].attrib[_rel_embed]if cNvPr:data[cNvPr] = embedreturn datadef level_order_traversal(root, flag):"""层次遍历,查找目标节点"""queue = [root]targets = []while queue:node = queue.pop(0)children = [child.tag for child in node]if flag in children:targets.append(node)continuefor child in node:queue.append(child)return targetsdef handle_images(deps, archive) -> []:"""将图片二进制内容封装为Image对象"""images = []if not PILImage:  # Pillow not installed, drop imagesreturn imagesfor dep in deps:if dep.Type != IMAGE_NS:msg = "{0} image format is not supported so the image is being dropped".format(dep.Type)print(msg)continuetry:image_io = archive.read(dep.target)image = Image(BytesIO(image_io))except OSError:msg = "The image {0} will be removed because it cannot be read".format(dep.target)print(msg)continueif image.format.upper() == "WMF":  # cannot savemsg = "{0} image format is not supported so the image is being dropped".format(image.format)print(msg)continueimage.embed = dep.id         # 文件rIdimage.target = dep.target    # 文件地址images.append(image)return imagesdef main():CELLIMAGE_PATH = "xl/cellimages.xml"PARSE_FILE_PATH = 'C:/Users/user/Downloads/测试文件.xlsx'archive = ZipFile(PARSE_FILE_PATH, "r")wb = load_workbook(PARSE_FILE_PATH)src = archive.read(CELLIMAGE_PATH)                              # 打开cellImage.xml文件deps = get_dependents(archive, get_rels_path(CELLIMAGE_PATH))   # 解析cellImage.xml._rel文件image_rels = handle_images(deps=deps.Relationship, archive=archive)node = fromstring(src)cellimages_xml = parse_element(node)cellimages_rel = {}for image in image_rels:cellimages_rel[image.embed] = imagefor cnvpr, embed in cellimages_xml.items():cellimages_xml[cnvpr] = cellimages_rel.get(embed)# df = pd.read_excel(PARSE_FILE_PATH)# df["行号"] = df.index + 2# image_mappings = ParserXLSXEmbed(wb=wb, df=df).extract_images(start_from=max(0, 1) + 1)# image_mappings.update(cellimages_xml)archive.close()  # 关闭压缩文件对象,防止内存泄漏print(cellimages_xml)if __name__ == '__main__':main()

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

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

相关文章

Ansible环境搭建,CentOS 系列操作系统搭建Ansible集群环境

Ansible是一种自动化工具&#xff0c;基于Python写的&#xff0c;原理什么的就不过多再说了&#xff0c;详情参考&#xff1a;https://www.itwk.cc/post/403.html https://blog.csdn.net/qq_34185638/article/details/131079320?spm1001.2014.3001.5502 环境准备 HOSTNAMEIP…

大后台,小前台——组合式创新加速推进产教融合

2023年8月1日&#xff0c;由成都知了汇智科技有限公司组织召开的“2023产教融合项目推进闭门研讨会”于成都市高新区软件园G8区7楼正式举行&#xff0c;本次会议基于“产业链的用人需求、资本链的回报诉求、服务链的价值要求、教育链的延伸需求”进行交流探讨&#xff0c;形成稳…

Java-认识String

目录 一、String概念及创建 1.1 String概念 1.2 String的创建 二、String常用方法 2.1 String对象的比较 2.2 字符串查找 2.3 转化 2.4 字符串替换 2.5 字符串拆分 2.6字符串的截取 2.7 其他操作方法 2.8 字符串修改 三、面试题 一、String概念及创建 1.1 String概念 Java中…

2023上半年手机及数码行业分析报告(京东销售数据分析)

2023年上半年&#xff0c;手机市场迎来复苏&#xff0c;同环比来看&#xff0c;销量销额纷纷上涨。 而数码市场中&#xff0c;各个热门品类表现不一。微单相机及智能手表同比去年呈现增长态势&#xff0c;而笔记本电脑市场则出现下滑。 基于此现状&#xff0c;鲸参谋发布了20…

Git Submodule 更新子库失败 fatal: Unable to fetch in submodule path

编辑本地目录 .git/config 文件 在 [submodule “Assets/CommonModule”] 项下 加入 fetch refs/heads/:refs/remotes/origin/

AWS Amplify 部署node版本18报错修复

Amplify env&#xff1a;Amazon Linux:2 Build Error : Specified Node 18 but GLIBC_2.27 or GLIBC_2.28 not found on build 一、原因 报错原因是因为默认情况下&#xff0c;AWS Amplify 使用 Amazon Linux:2 作为其构建镜像&#xff0c;并自带 GLIBC 2.26。不过&#xff0c;…

每天一道leetcode:剑指 Offer 04. 二维数组中的查找(中等二分查找)

今日份题目&#xff1a; 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右 非递减 的顺序排序&#xff0c;每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该整数。 示…

Qt中ffmpeg API存储和显示摄像头视频

Qt中ffmpeg API存储和显示摄像头视频的功能需要之前写的视频ffmpegAPI的视频播放的流程。 代码源码位置&#xff1a;https://download.csdn.net/download/qq_43812868/88157743?spm1001.2014.3001.5503 一、存储和显示摄像头的视频的流程 这是读取打开视频文件的流程&#x…

十三、ESP32PS2摇杆(ADC)

1. 运行效果 在上下左右操作PS2摇杆的时候,会检测到数据 2. 滑动电阻

Docker基本使用

查看本地镜像 查看本地&#xff1a;docker imagesPull镜像&#xff1a;docker pull nginx:latest登录镜像&#xff1a;docker login hub.docker.com -u **** -p ****制作镜像&#xff1a;docker build -t xxxx:v1push&#xff1a;docker push xxx:v1删除镜像:docker rmi #imag…

scikit-plot 使用笔记

scikit-plot是基于sklearn和Matplotlib的库&#xff0c;主要的功能是对训练好的模型进行可视化。 安装&#xff1a; pip install scikit-plot 功能1&#xff1a;评估指标可视化 scikitplot.metrics.plot_confusion_matrix快速展示模型预测结果和标签计算得到的混淆矩阵。 im…

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection (arXiv 2018)

图像 检测 - RetinaNet: Focal Loss for Dense Object Detection - 密集目标检测中的焦点损失&#xff08;arXiv 2018&#xff09; 摘要1. 引言2. 相关工作References 声明&#xff1a;此翻译仅为个人学习记录 文章信息 标题&#xff1a;RetinaNet: Focal Loss for Dense Obje…

java: 无法访问org.springframework.web.bind.annotation.GetMapping(springboot构建时出现问题)

spring boot构建完成后出现以下问题 报错原因&#xff1a;SpringBoot 3.0以上版本要求JDK 17以上&#xff0c;jdk版本1.8 与 spring boot 3.0.1 版本不匹配 解决方法&#xff1a;

线性代数(二) 矩阵及其运算

前言 行列式det(A) 其实表示的只是一个值 ∣ a b c d ∣ a d − b c \begin{vmatrix} a & b\\ c & d\end{vmatrix} ad -bc ​ac​bd​ ​ad−bc&#xff0c;其基本变化是基于这个值是不变。而矩阵表示的是一个数表。 定义 矩阵与线性变换的关系 即得 ( a 11 a 12…

Wisej.NET Crack,Wisej.NET的核心功能

Wisej.NET Crack&#xff0c;Wisej.NET的核心功能 Wisej.NET是一个跨平台的web框架&#xff0c;用于使用.NET和C#/VB.NET而不是HTML和JavaScript构建现代HTML5应用程序。它包含创建任务关键型web应用程序所需的一切&#xff0c;包括UI组件、会话处理、状态管理和后端集成。借助…

C语言代码的x86-64汇编指令分析过程记录

先通过Xcode创建一个terminal APP&#xff0c;语言选择C。代码如下&#xff1a; #include <stdio.h>int main(int argc, const char * argv[]) {int a[7]{1,2,3,4,5,6,7};int *ptr (int*)(&a1);printf("%d\n",*(ptr));return 0; } 在return 0处打上断点&…

R3LIVE项目实战(3) — 双目相机与激光雷达联合标定

目录 3.1 lidar_camera_calib简介 3.2 环境准备 3.3 编译 3.4 运行数据集 (1) 单场景标定 (2) 多场景标定 3.5 使用您自己的传感器设置 3.5.1 采集相机图片和雷达bag数据 3.5.2 使用多场景标定 3.5.3 相机内参获取 3.5.4 运行标定程序 3.5.5 验证结果 源码地址&am…

嵌入式基础知识-存储管理

上篇介绍了存储器的相关知识&#xff0c;偏重的是硬件结构&#xff0c;本篇介绍存储管理的相关知识&#xff0c;偏重的是软件管理。 1 存储管理概念 操作系统&#xff0c;包括嵌入式系统&#xff0c;通常利用存储管理单元MMU&#xff08;Memory Management Unit&#xff09;来…

填补5G物联一张网,美格智能快速推进RedCap商用落地

自5G R17版本标准冻结以来&#xff0c;RedCap一直引人注目。2023年更是5G RedCap突破性发展的一年&#xff0c;从首款5G RedCap调制解调器及射频系统——骁龙X35发布&#xff0c;到国内四大运营商发布RedCap技术白皮书&#xff0c;芯片厂商、模组厂商、运营商及终端企业都在积极…

Nginx(1)

目录 1.Nginx概述2.Nginx的特点3.Nginx主要功能1.反向代理2.负载均衡 1.Nginx概述 Nginx (engine x) 是一个自由的、开源的、高性能的HTTP服务器和反向代理服务器&#xff0c;也是一个IMAP、POP3、SMTP代理服务器。 Nginx是一个强大的web服务器软件&#xff0c;用于处理高并发…