Python读取wps中的DISPIMG图片格式

2024-06-16 06:28

本文主要是介绍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 openpyxlimage_list = []  # 存放从excel读出的DISPIMG_iddef 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:# 提取嵌入的图片 IDformula = cell.valuestart = formula.find('"') + 1end = 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 datadef 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 inroot1.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() ifembed in id_target_map}return name_to_target_mapdef 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'}

这篇关于Python读取wps中的DISPIMG图片格式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1065696

相关文章

使用Python删除Excel中的行列和单元格示例详解

《使用Python删除Excel中的行列和单元格示例详解》在处理Excel数据时,删除不需要的行、列或单元格是一项常见且必要的操作,本文将使用Python脚本实现对Excel表格的高效自动化处理,感兴... 目录开发环境准备使用 python 删除 Excphpel 表格中的行删除特定行删除空白行删除含指定

Python通用唯一标识符模块uuid使用案例详解

《Python通用唯一标识符模块uuid使用案例详解》Pythonuuid模块用于生成128位全局唯一标识符,支持UUID1-5版本,适用于分布式系统、数据库主键等场景,需注意隐私、碰撞概率及存储优... 目录简介核心功能1. UUID版本2. UUID属性3. 命名空间使用场景1. 生成唯一标识符2. 数

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

Python办公自动化实战之打造智能邮件发送工具

《Python办公自动化实战之打造智能邮件发送工具》在数字化办公场景中,邮件自动化是提升工作效率的关键技能,本文将演示如何使用Python的smtplib和email库构建一个支持图文混排,多附件,多... 目录前言一、基础配置:搭建邮件发送框架1.1 邮箱服务准备1.2 核心库导入1.3 基础发送函数二、

Python包管理工具pip的升级指南

《Python包管理工具pip的升级指南》本文全面探讨Python包管理工具pip的升级策略,从基础升级方法到高级技巧,涵盖不同操作系统环境下的最佳实践,我们将深入分析pip的工作原理,介绍多种升级方... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核

基于Python实现一个图片拆分工具

《基于Python实现一个图片拆分工具》这篇文章主要为大家详细介绍了如何基于Python实现一个图片拆分工具,可以根据需要的行数和列数进行拆分,感兴趣的小伙伴可以跟随小编一起学习一下... 简单介绍先自己选择输入的图片,默认是输出到项目文件夹中,可以自己选择其他的文件夹,选择需要拆分的行数和列数,可以通过

Python中反转字符串的常见方法小结

《Python中反转字符串的常见方法小结》在Python中,字符串对象没有内置的反转方法,然而,在实际开发中,我们经常会遇到需要反转字符串的场景,比如处理回文字符串、文本加密等,因此,掌握如何在Pyt... 目录python中反转字符串的方法技术背景实现步骤1. 使用切片2. 使用 reversed() 函

Python中将嵌套列表扁平化的多种实现方法

《Python中将嵌套列表扁平化的多种实现方法》在Python编程中,我们常常会遇到需要将嵌套列表(即列表中包含列表)转换为一个一维的扁平列表的需求,本文将给大家介绍了多种实现这一目标的方法,需要的朋... 目录python中将嵌套列表扁平化的方法技术背景实现步骤1. 使用嵌套列表推导式2. 使用itert

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker

Python使用vllm处理多模态数据的预处理技巧

《Python使用vllm处理多模态数据的预处理技巧》本文深入探讨了在Python环境下使用vLLM处理多模态数据的预处理技巧,我们将从基础概念出发,详细讲解文本、图像、音频等多模态数据的预处理方法,... 目录1. 背景介绍1.1 目的和范围1.2 预期读者1.3 文档结构概述1.4 术语表1.4.1 核