Python读取wps中的DISPIMG图片格式

需求:
读出excel的图片内容,这放在微软三件套是很容易的,但是由于wps的固有格式,会出现奇怪的问题,只能读出:类似于 =DISPIMG(“ID_2B83F9717AE1XXXX920xxxx644C80DB1”,1) 【该DISPIMG函数只有wps才拥有】

本文参考该多个作者的思路:
https://blog.csdn.net/maudboy/article/details/133145278 java读取Excel,(支持WPS嵌入式图片)
以及该github issus:
https://github.com/qax-os/excelize/issues/664 How to read pictures embedded in cells
当然该项目两个个月前用go 来读取wps中的图片格式:https://github.com/qax-os/excelize excelize

希望大家多多关注

github前几名的excel读取,python在后几名【这让我挺吃惊的,作为第一语言,支持库这么多,竟然没有对wps图片解析的python代码】,第一是Go写的。
在这里插入图片描述

首先明确,xlsx就是一个zip包,否则里面的图片根本没法读取。
下面是该代码的思路:

# xlsx本质就是zip,其解压文件夹为_rels xl docProps
# 代码思路:首先读取excel表,并提取DISPIMG_id列,保存在image_list中
# 根据xl/cellimages.xml 提取出rId与DISPIMG_id的关系,组成一个map1,{"DISPIMG_id":"rId"}
# 再根据xl/_rels/cellimages.xml.rels,根据rId 与 imgae_path的关系,组成一个map2 {"rId":"image_path"}
# 根据map1与map2对应的关系,组成一个新map3 : {"DISPIMG_id": "image_path"} 得出对应的关系
# 输出图片,根据xl/{image_path} 输出图片并把图片重命名为DISPIMG_id.png

代码思路,该代码可以优化,主要多次读取文件并且多次调用map了,不过处理几百条数据还是绰绰有余的。

import zipfile
import os
import xml.etree.ElementTree as ET
import openpyxl



image_list = []  # 存放从excel读出的DISPIMG_id


def read_excel_data(filename_path):
    # 加载 Excel 文件
    workbook = openpyxl.load_workbook(filename_path, data_only=False)
    sheet = workbook.active

    # 遍历数据和公式
    data = [] # data就是文本信息
    for row in sheet.iter_rows(min_row=1, values_only=False):
        row_data = []
        for cell in row:
            if cell.value and isinstance(cell.value, str) and '=_xlfn.DISPIMG(' in cell.value:
                # 提取嵌入的图片 ID
                formula = cell.value
                start = formula.find('"') + 1
                end = formula.find('"', start)
                image_id = formula[start:end]
                row_data.append(f"{image_id}")
                image_list.append(image_id)
                # print(image_id)
            else:
                # 其他数据直接添加
                row_data.append(cell.value)
        data.append(row_data)
    return data


def get_xml_id_image_map(xlsx_file_path):
    # 打开 XLSX 文件
    with zipfile.ZipFile(xlsx_file_path, 'r') as zfile:
        # 直接读取 XML 文件内容
        with zfile.open('xl/cellimages.xml') as file:
            xml_content = file.read()
        with zfile.open('xl/_rels/cellimages.xml.rels') as file:
            relxml_content = file.read()

    # 将读取的内容转换为 XML 树
    root = ET.fromstring(xml_content)

    # 初始化映射字典
    name_to_embed_map = {}

    # 命名空间
    namespaces = {
        'xdr': 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing',
        'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'
    }

    # 遍历所有 pic 元素
    for pic in root.findall('.//xdr:pic', namespaces=namespaces):
        name = pic.find('.//xdr:cNvPr', namespaces=namespaces).attrib['name']
        embed = pic.find('.//a:blip', namespaces=namespaces).attrib[
            '{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed']
        name_to_embed_map[name] = embed

    # 打印结果
    # print(name_to_embed_map)

    root1 = ET.fromstring(relxml_content)

    # 命名空间字典,根据 XML 中定义的命名空间进行设置
    namespaces = {'r': 'http://schemas.openxmlformats.org/package/2006/relationships'}

    # 创建 ID 和 Target 的映射
    id_target_map = {child.attrib['Id']: child.attrib.get('Target', 'No Target Found') for child in
                     root1.findall('.//r:Relationship', namespaces=namespaces)}

    # print(id_target_map)

    # 使用字典推导构建新的映射表
    name_to_target_map = {name: id_target_map[embed] for name, embed in name_to_embed_map.items() if
                          embed in id_target_map}
    return name_to_target_map


def output_id_image(xlsx_file_path):
    read_excel_data(xlsx_file_path)
    name_to_target_map = get_xml_id_image_map(xlsx_file_path)
    # 构建id_image_对
    new_map = {key: name_to_target_map.get(key) for key in image_list if key in name_to_target_map}
    print(new_map)
    output_directory = './images' #保存的图片目录
    # 打开xlsx文件(即Zip文件)
    with zipfile.ZipFile(xlsx_file_path, 'r') as zfile:
        for key, image_path in new_map.items():
            # 构建实际的图片路径
            actual_image_path = f'xl/{image_path}'  # 假设图片在'xl/media/'目录下
            if actual_image_path in zfile.namelist():
                # 读取图片内容
                with zfile.open(actual_image_path) as image_file:
                    image_content = image_file.read()
                    # 保存图片到新的文件,使用key作为文件名
                    new_file_path = os.path.join(output_directory, f"{key}.png")
                    with open(new_file_path, 'wb') as new_file:
                        new_file.write(image_content)
            else:
                print(f"File {actual_image_path} not found in the archive.")

if __name__ == '__main__':
    output_id_image('/home/jacin/Downloads/英式货表.xlsx')
    # 输出的图片名字就是 xlsx表中的列的DISPIMG_id,保存在images文件夹下
    # 并会在控制台输出一个字典,key是DISPIMG_id,value是图片的路径,例如:{'ID_BE7EFF591B6C4978XXXXXX5266': 'media/image118.png'}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

lua对接GPT4实现对话

演示效果: 准备材料: 1、FastWeb网站开发服务:fwlua.com 2、一台服务器 该示例使用开源项目:fastweb 实现。 代码比较简单,主要是两部分,一个lua代码和一个html页面,用来用户发起请求和后台…

Gradle实现类似Maven的profiles功能

版本说明 GraalVM JDK 21.0.3Gradle 8.7Spring Boot 3.2.5 目录结构 指定环境打包 application.yml/yaml/properties 执行 bootJar 打包命令前要先执行 clean【其它和 processResources 相关的命令也要先执行 clean】,否则 active 值不会变! spring…

最实用的 LeetCode 刷题指南

暑期实习基本结束了,校招即将开启。当前就业环境已不再是那个双向奔赴时代了。求职者在变多,岗位在变少,要求还更高了,最近社群又开始活跃起来了,各种讨论、各种卷。 为方便大家快手入手、节省时间,我整理…

永磁同步直线电机(PMLSM)控制与仿真3-永磁同步直线电机数学三环控制整定

文章目录 1、电流环参数整定2、速度环参数整定3、位置环参数整定 写在前面:原本为一篇文章写完了永磁同步直线电机数学模型介绍,永磁同步直线电机数学模型搭建,以及永磁同步直线电机三环参数整定及三环仿真模型搭建,但因为篇幅较长…

ComfyUI中使用 SD3 模型(附模型下载详细说明)

文章目录 背景安装方式一方式二 测试 背景 StabilityAI近日开源了Stable Diffusion 3 Medium,简称 SD3,该模型拥有着20亿参数。其特点如下: 提升了整体图片的质量、真实感提供了三种文本编码器可组合使用,有助于在性能和效率之间…

iOS18新增通话录音和应用锁!附升级教程及内置壁纸

一觉睡醒,iOS18终于是揭开面纱了,而且已经有测试版给开发者使用了。 不过还是建议咱们普通用户不要轻易尝试,而且在升级之前一定要用iMazing做个备份,以免测试系统出现问题,丢失数据。 这次WWDC2024与之前爆料完全一样…

【计算机网络仿真实验-实验2.6】带交换机的RIP路由协议

实验2.6 带交换机的rip路由协议 1. 实验拓扑图 2. 实验前查看是否能ping通 不能 3. 三层交换机配置 switch# configure terminal switch(config)# hostname s5750 !将交换机更名为S5750 S5750# configure terminal S5750(config)#vlan 10 S5750(config-vlan)#exit S57…

面向事件编程之观察者模式

前言 村里的老人常说:真男人就该懂得遵守“三不原则”——不主动、不拒绝、不负责。 一个复杂的软件系统,其中必然会存在各种各样的“对象”,如果在设计之初没有注意控制好耦合度,导致各个对象甚至是函数之间高度耦合&#xff0…

工业自动化领域常见的通讯协议

工业自动化领域常见的通讯协议,包括PROFINET、PROFIBUS、Modbus、Ethernet/IP、CANopen、DeviceNet和BACnet。通过分析这些协议的技术特点、应用场景及优势,比较它们在工业自动化中的性能和适用性,帮助选择最合适的协议以优化系统性能和可靠性…

记录AE快捷键(持续补充中。。。)

记录AE快捷键 快捷键常用快捷键图层快捷键工具栏图层与属性常用指令视图菜单时间轴常规快捷键项目首选项功能摄像机操作 常用操作导入AI/PS工程文件加选一个关键参数快速回到上下一帧隐藏/显示图层关键帧拉长缩短关键帧按着鼠标左键不松手,在秒表那一列往下移动会都…

为什么电源滤波器中的电容器太大

所有 AC-DC 转换器,无论是线性电源还是具有某种开关元件,都需要一种机制来获取交流侧的变化功率并在直流侧产生恒定功率。通常,大滤波电容器用于在交流功率高于直流负载所需时吸收和存储能量,并在交流功率低于所需时向负载提供能量…

常用的JDK调优监控工具整理

JVM 调优首先要做的就是监控 JVM 的运行状态,这就需要用到各种官方和第三方的工具包了 一、 JDK 工具包 JDK 自带的 JVM 工具可以分为命令行工具和可视化工具 命令行工具 jps: JVM Process status tool:JVM进程状态工具,查看进程基本信息j…

DomoAI让你轻松变身视频达人!支持20s完整视频生成!

账号注册 官网:https://www.domoai.app/zh-Hant/library 功能 支持不同风格的视频类型,支持图片转视频,支持文字转图片,支持静态图片变为动态。 可以切换语言为中文 风格转换 选择不同风格的 支持生成20s,目前接触…

0. 云原生之基于乌班图远程开发

云原生专栏大纲 文章目录 安装乌班图配置静态IP重置root密码开启root远程登录开启远程SSH访问安装docker安装docker-compose安装Edge浏览器安装搜狗输入法安装TeamViewer安装虚拟显示器安装JDK安装maven安装vscodevscode插件安装VSCode配置maven、git、jdk、自动报错vscode快捷…

2024年【陕西省安全员C证】考试及陕西省安全员C证最新解析

题库来源:安全生产模拟考试一点通公众号小程序 陕西省安全员C证考试参考答案及陕西省安全员C证考试试题解析是安全生产模拟考试一点通题库老师及陕西省安全员C证操作证已考过的学员汇总,相对有效帮助陕西省安全员C证最新解析学员顺利通过考试。 1、【多…

树以及二叉树的定义和特点

目录 开场白 树的定义 结点的分类 结点间的关系 树的其他相关概念 树的存储结构 孩子兄弟表示法 二叉树的定义 二叉树的特点 特殊二叉树 满二叉树 完全二叉树 二叉树的性质 二叉树的存储结构 开场白 这一篇文章是关于树的知识,这是一个比较特…

Python 学习 用Python第二册 第9章内容解八皇后问题

----用教授的方法学习 目录 1.八皇后问题 2.状态表示(抽象) 3.检测冲突 4.基线条件 5.递归条件 6.结尾 1.八皇后问题 深受大家喜爱的计算机科学谜题:你需要将8个皇后放在棋盘上,条件是任何一个皇后都不能威胁其他皇后,即任何两个皇后…

利用485缓存器实现两主一丛RS485串行通信

作者:艺捷自动化,其旗下产品有艺捷自动化网站和易为二维码小程序(微信) 对于工控自动化领域的电气工程师来说,基于RS485的串行通讯是最常见的。绝大部分仪表都能支持这种通讯方式。RS485通讯,是一种异步半双工模式&…

誉天5月红帽战报:恭喜14名学员通过RHCE认证,通过率87.5%!

红帽认证是全球公认的Linux权威认证之一,对于Linux从业者来说具有很高的价值和认可度。旨在评估考生在Linux系统管理和应用方面的专业知识和技能。红帽考试是Linux从业者提升自身技能水平和职业竞争力的重要途径之一。 5月份,誉天14名学员通过了RHCE认证…

css入门宝典

3.1.4 通配符选择器 语法 : *{} 作用 : 让页面中所有的标签执行该样式,通常用来清除间距 例子 : *{ margin: 0; //外间距 padding: 0; //内间距 } 一 CSS基本语法 1基础知识 1.1概述 Css (层叠样式表)是种格式化网页的标准方式, 用于控制设置网页的样式&#xff…