You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用openpyxl加载含大量绘图的Excel文件时触发TypeError异常的解决方案求助

Solutions for Loading Excel Files with Drawings/Charts in Python

First off, let's tackle your problem step by step—those DrawingML errors from openpyxl are definitely a pain when dealing with complex Excel reports. Here are a few actionable solutions, ordered by simplicity:

1. Try Openpyxl's Read-Only Mode (Quickest Fix)

Openpyxl's read_only=True mode skips loading graphical elements like charts, images, and text boxes entirely. Since you only need to read cell content for your table of contents, this might bypass the error completely:

import openpyxl as pyxl
# Enable read-only mode to skip drawing/chart processing
wbook = pyxl.load_workbook(path, data_only=True, read_only=True)

Note: Read-only mode doesn't allow modifying the file, but for reading cell values (which is all you need for generating a TOC), this should work perfectly.

2. Create a Cleaned Copy of the Excel File (Cross-Platform)

If read-only mode still throws errors, you can manually strip out all drawing/chart-related components from the Excel file (since Excel files are just zip archives under the hood). This script will create a copy of your file without any graphical elements:

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

def clean_excel_file(input_path, output_path):
    # Define XML namespaces used in Excel files
    ns = {
        'main': 'http://schemas.openxmlformats.org/spreadsheetml/2006/main',
        'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
    }

    with zipfile.ZipFile(input_path, 'r') as in_zip, zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as out_zip:
        for item in in_zip.infolist():
            # Skip the entire drawings folder and its contents
            if item.filename.startswith('xl/drawings/'):
                continue
            
            # Skip worksheet relationship files linked to drawings
            if item.filename.startswith('xl/worksheets/_rels/') and 'drawing' in item.filename:
                continue
            
            content = in_zip.read(item)
            
            # Remove drawing references from worksheet XMLs
            if item.filename.startswith('xl/worksheets/sheet') and item.filename.endswith('.xml'):
                tree = ET.fromstring(content)
                for drawing in tree.findall('.//main:drawing', ns):
                    parent = drawing.findall('..')[0]
                    parent.remove(drawing)
                content = ET.tostring(tree, encoding='utf-8')
            
            # Remove drawing entries from workbook relationships
            if item.filename == 'xl/_rels/workbook.xml.rels':
                tree = ET.fromstring(content)
                for rel in tree.findall('.//r:Relationship', ns):
                    if rel.get('Type') == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing':
                        parent = rel.findall('..')[0]
                        parent.remove(rel)
                content = ET.tostring(tree, encoding='utf-8')
            
            out_zip.writestr(item, content)

# Usage example
input_file = 'path/to/your/report.xlsx'
cleaned_file = 'path/to/cleaned_report.xlsx'
clean_excel_file(input_file, cleaned_file)

# Now load the cleaned file normally
wbook = pyxl.load_workbook(cleaned_file, data_only=True)

This script:

  • Deletes the entire xl/drawings folder (where charts/images are stored)
  • Removes references to drawings from worksheet XML files
  • Cleans up workbook relationship entries linked to drawings

3. Use Excel Automation (Windows-Only, Requires Excel Installed)

If you're on Windows and have Microsoft Excel installed, you can use win32com to automate Excel to remove all charts and shapes directly. This is reliable because it uses Excel's own logic:

import win32com.client as win32
import os

def remove_excel_elements(input_path, output_path):
    excel = win32.Dispatch('Excel.Application')
    excel.Visible = False  # Run in background to avoid popping up Excel
    
    try:
        workbook = excel.Workbooks.Open(os.path.abspath(input_path))
        
        # Remove all charts and shapes from each worksheet
        for sheet in workbook.Sheets:
            # Delete chart objects
            while sheet.ChartObjects().Count > 0:
                sheet.ChartObjects(1).Delete()
            # Delete shapes (images, text boxes, etc.)
            while sheet.Shapes.Count > 0:
                sheet.Shapes(1).Delete()
        
        workbook.SaveAs(os.path.abspath(output_path))
    finally:
        workbook.Close()
        excel.Quit()

# Usage example
input_file = 'path/to/your/report.xlsx'
cleaned_file = 'path/to/cleaned_report.xlsx'
remove_excel_elements(input_file, cleaned_file)

# Load the cleaned file with openpyxl
wbook = pyxl.load_workbook(cleaned_file, data_only=True)

Recommendation

Start with the read-only mode—it's the quickest and simplest solution. If that doesn't work, use the zip modification script (it's cross-platform and doesn't require Excel). If you're on Windows and have Excel installed, the automation approach is also a solid choice.

内容的提问来源于stack exchange,提问作者Dervissss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 11:32:44