Python解析Excel图表Chart的信息实战指南

 更新时间:2026年01月19日 09:42:35   作者:weixin_46244623  
在数据分析与报表自动化场景中,Excel图表往往承载着关键业务信息,本文将基于OpenXML规范,通过将.xlsx文件视为ZIP压缩包,直接解析 xl/charts/chart*.xml,实现了对 Excel 图表元数据的精准提取,感兴趣的小伙伴可以了解下

摘要

在数据分析与报表自动化场景中,Excel 图表往往承载着关键业务信息,但常规库对图表结构与样式的解析能力有限。本文基于 OpenXML 规范,通过将 .xlsx 文件视为 ZIP 压缩包,直接解析 xl/charts/chart*.xml,实现了对 Excel 图表元数据的精准提取。使用 Python 的 urllib、zipfile 与 xml.etree.ElementTree,完整获取了图表标题、系列名称、X/Y 轴数据,以及标题、坐标轴和数据系列的字体与字号信息。实践结果表明,该方法无需依赖 Excel 环境,适用于线上 Excel 文件解析、图表规范校验及报表自动化处理,为 Excel 图表的深度解析与二次利用提供了一种高效可行的技术方案。

一、背景介绍

在实际项目中,我们经常会遇到这样的需求:

线上 Excel 文件(HTTP 地址)

不关心单元格数据,而是需要:

  • 图表标题
  • 系列名称
  • X / Y 轴数据
  • 图表、坐标轴、系列的字体和字号

然而,openpyxl 等库并不能完整解析 Excel 图表的样式和结构

事实上,.xlsx 本质上是一个 ZIP 压缩包,图表信息存储在:

xl/charts/chart*.xml

只要我们直接解析这个 XML,就能拿到几乎全部图表元数据。

二、整体思路

技术路线

1.通过 urllib 下载 Excel 文件

2.使用 ZipFile 读取 xlsx 内部结构

3.定位 xl/charts/chart1.xml

4.使用 xml.etree.ElementTree 解析图表 XML

5.按 OpenXML 规范解析:

  • 标题(title)
  • 系列(ser)
  • 分类轴(catAx)
  • 数值轴(valAx)
  • 字体、字号
  • X / Y 轴数据

三、核心代码实现

完整函数代码

import xml.etree.ElementTree as ET
from zipfile import ZipFile
import io
import urllib.request

def get_chat_info(direct_link):
    result = {}
    res = {}

    try:
        # 下载 Excel 文件
        file = urllib.request.urlopen(direct_link).read()
        archive = ZipFile(io.BytesIO(file))

        try:
            # 读取图表 XML
            data = archive.read('xl/charts/chart1.xml')
            res['code'] = 200
            res['msg'] = "获取图表信息成功"

            tree = ET.parse(io.BytesIO(data))
            root = tree.getroot()

            # 命名空间
            ns = {
                'c': 'http://schemas.openxmlformats.org/drawingml/2006/chart',
                'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'
            }

            # ================== 图表标题 ==================
            title_element = root.find('.//c:title/c:tx/c:rich', ns)
            if title_element is not None:
                title_text = ""
                for t in title_element.iter('{http://schemas.openxmlformats.org/drawingml/2006/main}t'):
                    title_text += t.text
                result['title'] = title_text

            title_ax_element = root.find('.//c:chart/c:title/c:tx', ns)
            if title_ax_element is not None:
                tx_pr = title_ax_element.find('.//a:defRPr', ns)
                if tx_pr is not None:
                    latin = tx_pr.find('.//a:latin', ns)
                    result['title_font'] = latin.get('typeface') if latin is not None else "no"
                    result['title_size'] = tx_pr.get('sz') or "no"

            # ================== 系列名称 ==================
            ser_elements = root.findall('.//c:chart/c:plotArea/*/c:ser', ns)
            series_name = ""
            for ser in ser_elements:
                v = ser.find('.//c:v', ns)
                if v is not None:
                    series_name = v.text
            result['series_name'] = series_name

            # ================== X / Y 数据 ==================
            x_values, y_values = [], []

            for num_ref in root.findall('.//c:numRef', ns):
                for v in num_ref.findall('.//c:v', ns):
                    y_values.append(v.text)

            for pt in root.findall('.//c:cat/c:strRef/c:strCache/c:pt', ns):
                v = pt.find('.//c:v', ns)
                if v is not None:
                    x_values.append(v.text)

            result['x_values'] = x_values
            result['y_values'] = y_values

            # ================== 数值轴 ==================
            val_ax = root.find('.//c:valAx', ns)
            if val_ax is not None:
                tx_pr = val_ax.find('.//c:txPr/a:p/a:pPr/a:defRPr', ns)
                if tx_pr is not None:
                    latin = tx_pr.find('.//a:latin', ns)
                    result['valAx_font'] = latin.get('typeface') if latin is not None else "no"
                    result['valAx_size'] = tx_pr.get('sz') or "no"

            # ================== 分类轴 ==================
            cat_ax = root.find('.//c:catAx', ns)
            if cat_ax is not None:
                tx_pr = cat_ax.find('.//c:txPr/a:p/a:pPr/a:defRPr', ns)
                if tx_pr is not None:
                    latin = tx_pr.find('.//a:latin', ns)
                    result['catAx_font'] = latin.get('typeface') if latin is not None else "no"
                    result['catAx_size'] = tx_pr.get('sz') or "no"

            # ================== 系列字体 ==================
            ser = root.find('.//c:chart/c:plotArea/*/c:ser', ns)
            if ser is not None:
                tx_pr = ser.find('.//a:defRPr', ns)
                if tx_pr is not None:
                    latin = tx_pr.find('.//a:latin', ns)
                    result['ser_font'] = latin.get('typeface') if latin is not None else "no"
                    result['ser_size'] = tx_pr.get('sz') or "no"

            res['data'] = result

        except:
            res['code'] = 404
            res['msg'] = "未找到图表信息"

    except:
        res['code'] = 500
        res['msg'] = "未获取excel信息"

    return res

测试示例

aa = get_chat_info("http://192.168.31.161:8080/555.xlsx")
print(aa)

四、运行结果示例

{
  "code": 200,
  "msg": "获取图表信息成功",
  "data": {
    "title": "各季度采购合理性折线图",
    "title_font": "宋体",
    "title_size": "1200",
    "series_name": "采购合理性",
    "x_values": [
      "2018-1", "2018-2", "2018-3", "2018-4",
      "Jan-19", "2019-2", "2019-3", "2019-4",
      "2020-1", "2020-2", "2020-3", "2020-4",
      "2021-1", "2021-2", "2021-3", "2021-4",
      "2022-1", "2022-2", "2022-3", "2022-4"
    ],
    "y_values": [
      "0.99", "0.92", "0.91", "0.37", "0.85",
      "0.97", "0.8", "0.88", "0.67", "0.91",
      "0.76", "0.75", "0.99", "0.95", "0.89",
      "0.83", "0.44", "0.75", "0.94", "0.41"
    ],
    "valAx_font": "宋体",
    "valAx_size": "1000",
    "catAx_font": "宋体",
    "catAx_size": "1000",
    "ser_font": "宋体",
    "ser_size": "1000"
  }
}

五、关键知识点总结

.xlsx 是 ZIP 文件

图表数据在 xl/charts/chart*.xml

Excel 图表完全遵循 OpenXML 规范

字体大小单位为 1/100 磅(pt)

  • 1000 = 10pt
  • 1200 = 12pt

六、适用场景

  • 自动化审计 Excel 报表
  • 图表规范校验(字体 / 标题 / 数据完整性)
  • Excel → 图表数据 → Web 可视化
  • 报表 AI / LLM 解析前的数据结构化

延伸:Python使用openpyxl从URL读取Excel并获取单元格样式

到此这篇关于Python解析Excel图表Chart的信息实战指南的文章就介绍到这了,更多相关Python解析Excel图表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python成功解决读文件出现:IOError: [Errno 0] Error的错误

    Python成功解决读文件出现:IOError: [Errno 0] Error的错误

    在Python编程中,处理文件是常见的任务之一,但偶尔也会遇到各种错误,包括IOError,尽管Python 3.x中IOError已被OSError和FileNotFoundError等更具体的异常所取代,由于[Errno 0]不直接指向具体的错误类型,我们将讨论一系列可能导致IOError的常见情况,需要的朋友可以参考下
    2024-07-07
  • 深入理解pytorch库的dockerfile

    深入理解pytorch库的dockerfile

    这篇文章主要介绍了pytorch库的dockerfile,主要包括dockerfile命令,使用指令的注意点及存在的一些问题,本文给大家介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • flask中使用SQLAlchemy进行辅助开发的代码

    flask中使用SQLAlchemy进行辅助开发的代码

    在Web.py, Django, Flask, Tornado里,自带的ORM功能比较缺乏,推荐大家使用SQLAlchemy来辅助开发
    2013-02-02
  • python判断变量是否为列表的方法

    python判断变量是否为列表的方法

    在本篇文章里小编给大家整理了关于python判断变量是否为列表的方法,有需要的朋友们可以学习下。
    2020-09-09
  • Python实现高精度敏感词过滤

    Python实现高精度敏感词过滤

    这篇文章主要为大家详细介绍了Python中实现高精度敏感词过滤的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-03-03
  • 修改 CentOS 6.x 上默认Python的方法

    修改 CentOS 6.x 上默认Python的方法

    这篇文章主要介绍了修改 CentOS 6.x 上默认Python的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • Python读取中文路径出现乱码问题的解决方案

    Python读取中文路径出现乱码问题的解决方案

    小编在使用opencv读取带有中文路径的图片时,发现会出现乱码的情况,当读取的文件路径出现中文时,(文件夹名为中文或者文件为中文)出现错误,所以本文给大家介绍了Python读取中文路径出现乱码问题的解决方案,需要的朋友可以参考下
    2024-06-06
  • 使用Python写个小监控

    使用Python写个小监控

    最近使用python写了个小监控,为什么使用python?简单、方便、好管理,Python如何实现简单的小监控,感兴趣的小伙伴们可以参考一下
    2016-01-01
  • Tensorflow 查看变量的值方法

    Tensorflow 查看变量的值方法

    今天小编就为大家分享一篇Tensorflow 查看变量的值方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-06-06
  • python3使用print打印带颜色的字符串代码实例

    python3使用print打印带颜色的字符串代码实例

    这篇文章主要介绍了python3使用print打印带颜色的字符串代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08

最新评论