openpyxl load_workbook 错误 expected <class ‘str‘>

博客讲述了在使用openpyxl处理Excel文件时遇到的一个问题,即openpyxl在处理ExternalData时会丢失ID属性,导致初始化类时出现错误。作者提出了一个解决方案,即通过正则表达式删除含有ExternalData的XML元素,从而避免报错。提供的代码示例展示了如何在不修改openpyxl源码的情况下实现这一操作。

Google很多方法都不行,唯有自己看源码。

发现openpyxl处理ExternalData时会把ID解析为{http://schemas.openxmlformats.org/officeDocument/2006/relationships}id,从而丢失了ID的属性,当初始化类的时候就会因为ID值缺失而报错。

在不修改openpyxl的代码情况下,最可行的是把ExternalData的xml元素删掉。

# 除去图表的externalData属性,以便openpyxl读取
externalData_REGEX = re.compile(b'<c:externalData.*</c:externalData>')

with zipfile.ZipFile(f_电渠日报) as zf:
    excel_obj = {zi.filename:zf.read(zi) for zi in zf.filelist}
    
with zipfile.ZipFile(f_电渠日报,'w') as zf1:
    for zi, duffer in excel_obj.items():
        zf1.writestr(zi,externalData_REGEX.sub(b'',duffer))

TypeError Traceback (most recent call last) Cell In[9], line 15 13 file_path = os.path.join(folder_path, filename) 14 # 读取Excel文件 ---> 15 df = pd.read_excel(file_path) 16 # 将读取的数据追加到总表中 17 all_df = pd.concat([all_df, df], ignore_index=True) File /opt/anaconda3/lib/python3.12/site-packages/pandas/io/excel/_base.py:495, in read_excel(io, sheet_name, header, names, index_col, usecols, dtype, engine, converters, true_values, false_values, skiprows, nrows, na_values, keep_default_na, na_filter, verbose, parse_dates, date_parser, date_format, thousands, decimal, comment, skipfooter, storage_options, dtype_backend, engine_kwargs) 493 if not isinstance(io, ExcelFile): 494 should_close = True --> 495 io = ExcelFile( 496 io, 497 storage_options=storage_options, 498 engine=engine, 499 engine_kwargs=engine_kwargs, 500 ) 501 elif engine and engine != io.engine: 502 raise ValueError( 503 "Engine should not be specified when passing " 504 "an ExcelFile - ExcelFile already has the engine set" 505 ) File /opt/anaconda3/lib/python3.12/site-packages/pandas/io/excel/_base.py:1567, in ExcelFile.__init__(self, path_or_buffer, engine, storage_options, engine_kwargs) 1564 self.engine = engine 1565 self.storage_options = storage_options -> 1567 self._reader = self._engines[engine]( 1568 self._io, 1569 storage_options=storage_options, 1570 engine_kwargs=engine_kwargs, 1571 ) File /opt/anaconda3/lib/python3.12/site-packages/pandas/io/excel/_openpyxl.py:553, in OpenpyxlReader.__init__(self, filepath_or_buffer, storage_options, engine_kwargs) 541 """ 542 Reader using openpyxl engine. 543 (...) 550 Arbitrary keyword arguments passed to excel engine. 551 """ 552 import_optional_dependency("openpyxl") --> 553 super().__init__( 554 filepath_or_buffer, 555 storage_options=storage_options, 556 engine_kwargs=engine_kwargs, 557 ) File /opt/anaconda3/lib/python3.12/site-packages/pandas/io/excel/_base.py:573, in BaseExcelReader.__init__(self, filepath_or_buffer, storage_options, engine_kwargs) 571 self.handles.handle.seek(0) 572 try: --> 573 self.book = self.load_workbook(self.handles.handle, engine_kwargs) 574 except Exception: 575 self.close() File /opt/anaconda3/lib/python3.12/site-packages/pandas/io/excel/_openpyxl.py:572, in OpenpyxlReader.load_workbook(self, filepath_or_buffer, engine_kwargs) 568 from openpyxl import load_workbook 570 default_kwargs = {"read_only": True, "data_only": True, "keep_links": False} --> 572 return load_workbook( 573 filepath_or_buffer, 574 **(default_kwargs | engine_kwargs), 575 ) File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/reader/excel.py:346, in load_workbook(filename, read_only, keep_vba, data_only, keep_links, rich_text) 316 """Open the given filename and return the workbook 317 318 :param filename: the path to open or a file-like object (...) 342 343 """ 344 reader = ExcelReader(filename, read_only, keep_vba, 345 data_only, keep_links, rich_text) --> 346 reader.read() 347 return reader.wb File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/reader/excel.py:299, in ExcelReader.read(self) 297 self.read_theme() 298 action = "read stylesheet" --> 299 apply_stylesheet(self.archive, self.wb) 300 action = "read worksheets" 301 self.read_worksheets() File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/styles/stylesheet.py:198, in apply_stylesheet(archive, wb) 195 return wb 197 node = fromstring(src) --> 198 stylesheet = Stylesheet.from_tree(node) 200 if stylesheet.cell_styles: 202 wb._borders = IndexedList(stylesheet.borders) File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/styles/stylesheet.py:103, in Stylesheet.from_tree(cls, node) 101 for k in attrs: 102 del node.attrib[k] --> 103 return super(Stylesheet, cls).from_tree(node) File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/descriptors/serialisable.py:87, in Serialisable.from_tree(cls, node) 84 else: 85 if hasattr(desc.expected_type, "from_tree"): 86 #complex type ---> 87 obj = desc.expected_type.from_tree(el) 88 else: 89 #primitive 90 obj = el.text File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/descriptors/serialisable.py:87, in Serialisable.from_tree(cls, node) 84 else: 85 if hasattr(desc.expected_type, "from_tree"): 86 #complex type ---> 87 obj = desc.expected_type.from_tree(el) 88 else: 89 #primitive 90 obj = el.text File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/descriptors/serialisable.py:103, in Serialisable.from_tree(cls, node) 100 else: 101 attrib[tag] = obj --> 103 return cls(**attrib) File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/styles/named_styles.py:229, in _NamedCellStyle.__init__(self, name, xfId, builtinId, iLevel, hidden, customBuiltin, extLst) 220 def __init__(self, 221 name=None, 222 xfId=None, (...) 227 extLst=None, 228 ): --> 229 self.name = name 230 self.xfId = xfId 231 self.builtinId = builtinId File /opt/anaconda3/lib/python3.12/site-packages/openpyxl/descriptors/base.py:46, in Typed.__set__(self, instance, value) 44 if DEBUG: 45 msg = f"{instance.__class__}.{self.name} should be {self.expected_type} but {value} is {type(value)}" ---> 46 raise TypeError(msg) 47 super(Typed, self).__set__(instance, value) TypeError: <class 'openpyxl.styles.named_styles._NamedCellStyle'>.name should be <class 'str'> but value is <class 'NoneType'>
最新发布
10-15
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值