如何通过解析 Excel XML 提取形状的文本内容与填充/边框颜色

千敏同学_4059

千敏同学_4059

2026-06-29

911人浏览

原创

如何通过解析 Excel XML 提取形状的文本内容与填充/边框颜色

本文介绍如何使用 Python(zipfile + lxml)直接解析 Excel .xlsx 文件的 Drawing XML,高效提取形状的文本内容、填充色(solid fill)及边框色(line color),规避 xlwings/pywin32 的性能开销,且无需 openpyxl 支持。

本文介绍如何使用 python(zipfile + lxml)直接解析 excel `.xlsx` 文件的 drawing xml,高效提取形状的文本内容、填充色(solid fill)及边框色(line color),规避 xlwings/pywin32 的性能开销,且无需 openpyxl 支持。

Excel 的 .xlsx 文件本质上是 ZIP 压缩包,其中每个工作表对应的图形信息存储在 xl/drawings/drawing*.xml 文件中。这些 XML 遵循 Office Open XML 标准,包含 (shape)元素及其样式定义 (shape properties),而颜色信息就嵌套在 (填充)和 (线条)子节点内。

要同时提取文本与颜色,需对原始代码进行两处关键增强:

  1. 扩展 XPath 表达式,精准定位文本内容、填充色值(a:solidFill/a:srgbClr/@val)和边框色值(a:ln/a:solidFill/a:srgbClr/@val);
  2. 结构化组织结果,将每个形状的文本、几何类型(如 ellipse)、填充色和边框色统一成可读格式(如字典或元组)。

以下是完整、健壮的实现示例:

excel-clean
excel-clean

Excel 数据清洗——去重、填补缺失值、格式转换。

下载
from zipfile import ZipFile
from lxml import etree

def extract_shapes_with_color(xlsx_path):
    ns = {
        "xdr": "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
        "a": "http://schemas.openxmlformats.org/drawingml/2006/main",
        "r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships"
    }

    shapes_data = []

    with ZipFile(xlsx_path) as z:
        # 定位所有 drawing XML 文件(如 drawing1.xml, drawing2.xml)
        drawing_files = [f for f in z.filelist if "drawings/drawing" in f.filename and f.filename.endswith(".xml")]

        for drw in drawing_files:
            with z.open(drw.filename) as f:
                tree = etree.fromstring(f.read())

                # 提取文本:仅针对有 spPr 且含 txBody 的形状(即含文字的形状)
                texts = tree.xpath('//xdr:txBody[preceding-sibling::xdr:spPr]/a:p/a:r/a:t/text()', namespaces=ns)

                # 提取样式属性:几何类型、填充色、边框色(按顺序匹配)
                # 注意:XPath 返回扁平列表,需按语义分组(每形状最多 1 个几何 + 1 个填充 + 1 个边框)
                shape_attrs = tree.xpath(
                    '//xdr:spPr/a:prstGeom/@prst | '
                    '//xdr:spPr/a:solidFill/a:srgbClr/@val | '
                    '//xdr:spPr/a:ln/a:solidFill/a:srgbClr/@val',
                    namespaces=ns
                )

                # 按形状分组:每个 <sp> 对应一组属性,但 XPath 不自动分组 → 需结合节点层级更稳健的方式
                # 更推荐:遍历每个 <sp>,分别提取其内部属性(如下所示)
                sp_nodes = tree.xpath('//xdr:sp', namespaces=ns)
                for i, sp in enumerate(sp_nodes):
                    # 获取文本(若存在)
                    text = ""
                    t_node = sp.xpath('.//xdr:txBody/a:p/a:r/a:t/text()', namespaces=ns)
                    if t_node:
                        text = "".join(t_node).strip()

                    # 获取几何类型
                    geom = sp.xpath('.//a:prstGeom/@prst', namespaces=ns)
                    geometry = geom[0] if geom else "custom"

                    # 获取填充色(solid fill)
                    fill = sp.xpath('.//a:solidFill/a:srgbClr/@val', namespaces=ns)
                    fill_color = fill[0] if fill else None

                    # 获取边框色(line solid fill)
                    line_fill = sp.xpath('.//a:ln/a:solidFill/a:srgbClr/@val', namespaces=ns)
                    line_color = line_fill[0] if line_fill else None

                    shapes_data.append({
                        "text": text,
                        "geometry": geometry,
                        "fill_color": fill_color,   # 6位十六进制 RGB,如 "729fcf"
                        "line_color": line_color    # 如 "3465a4"
                    })

    return shapes_data

# 使用示例
if __name__ == "__main__":
    result = extract_shapes_with_color("/home/luis/tmp/shapes.xlsx")
    for i, shape in enumerate(result, 1):
        print(f"Shape {i}: '{shape['text']}' | {shape['geometry']} | Fill: #{shape['fill_color']} | Line: #{shape['line_color']}")</sp></sp>

注意事项与最佳实践:

  • ✅ 颜色格式说明:@val 属性返回的是小写、无 # 前缀的 6 位十六进制 RGB 值(如 "ff0000" 表示红色),使用时可直接拼接 # 构成标准 CSS 颜色。
  • ⚠️ 空值处理:并非所有形状都有填充或边框,xpath() 可能返回空列表,务必用 if xxx else None 防止索引错误。
  • ? 调试技巧:解压 .xlsx 后手动打开 xl/drawings/drawing1.xml,用浏览器或 VS Code 的 XML 工具查看结构;右键元素 → “Copy XPath” 可快速生成路径,再精简为通用表达式(如将 /xdr:wsDr/xdr:twoCellAnchor[2]/xdr:sp/xdr:spPr/... 简化为 //xdr:sp//a:solidFill/a:srgbClr/@val)。
  • ? 不支持渐变/图案填充:本方案仅覆盖 a:solidFill;若需处理 a:gradFill 或 a:pattFill,需扩展 XPath 并解析对应子节点(如 a:gradFill/a:gsLst/a:gs/@pos 和 a:gs/a:srgbClr/@val)。

该方法完全基于标准库与轻量级 lxml,毫秒级完成百页 Excel 的形状批量解析,是自动化报表分析、模板校验与 UI 一致性检查的理想技术选型。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

excel

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

2023.07.20

1671

4

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

2023.07.25

4164

7

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.07.31

1669

3

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

2023.08.03

24057

23

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2947

5

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.04

2967

5

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

1143

5

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.10

596

4

python是前端还是后端
python是前端还是后端

Python属于前端也属于后端,其灵活性和丰富的生态系统使得开发人员能够在不同的领域中灵活运用。本专题为大家提供python相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.11

2303

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 43.9万人学习

成为PHP架构师-自制PHP框架
成为PHP架构师-自制PHP框架

共28课时 | 3.5万人学习