使用pandas.read_excel读取.xls文件触发IndexError,求排查方案
问题:pandas+xlrd读取xls文件报IndexError,另存为xlsx正常
环境版本
- pandas 2.2.0
- xlrd 2.0.1
执行代码
import pandas as pd filepath = './data/myfile.xls' df = pd.read_excel(filepath)
报错日志
Traceback (most recent call last): File "/home/singhd/PycharmProjects/Debugging/main.py", line 30, in <module> df = pd.read_excel(file_path) ^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/pandas/io/excel/_base.py", line 495, in read_excel io = ExcelFile( ^^^^^^^^^^ File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/pandas/io/excel/_base.py", line 1567, in __init__ self._reader = self._engines[engine]( ^^^^^^^^^^^^^^^^^^^^^^ File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/pandas/io/excel/_xlrd.py", line 46, in __init__ super().__init__( File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/pandas/io/excel/_base.py", line 573, in __init__ self.book = self.load_workbook(self.handles.handle, engine_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/pandas/io/excel/_xlrd.py", line 63, in load_workbook return open_workbook(file_contents=data, **engine_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/xlrd/__init__.py", line 172, in open_workbook bk = open_workbook_xls( ^^^^^^^^^^^^^^^^^^ File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/xlrd/book.py", line 68, in open_workbook_xls bk.biff2_8_load( File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/xlrd/book.py", line 637, in biff2_8_load cd = compdoc.CompDoc(self.filestr, logfile=self.logfile, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/xlrd/compdoc.py", line 227, in __init__ dbytes = self._get_stream( ^^^^^^^^^^^^^^^^^ File "/home/singhd/PycharmProjects/Debugging/.venv/lib/python3.11/site-packages/xlrd/compdoc.py", line 293, in _get_stream if self.seen[s]: ~~~~~~~~~^^^ IndexError: array index out of range
现象说明
将该.xls文件用Excel打开并另存为.xlsx后即可正常读取,说明文件本身未损坏。
问题原因
这个报错是xlrd 2.0.1在解析特定格式xls文件时的兼容性问题:
- 部分xls文件可能由非微软Excel的工具生成(比如老旧办公软件、自动化导出脚本),其内部的复合文档结构(CompDoc)不符合xlrd 2.x版本的解析逻辑,导致在
_get_stream方法中访问数组时出现索引越界。 - 另存为xlsx后,文件转为OOXML格式,此时pandas默认使用openpyxl引擎读取,避开了xlrd对xls格式的解析缺陷。
排查方法
- 验证文件来源与重存:确认xls文件的生成工具,若为第三方工具导出,尝试用原生Excel重新保存为xls格式(而非xlsx),再测试读取。
- 更换xlrd版本:降级xlrd到1.2.0版本(该版本对老旧xls格式兼容性更好),执行命令:
重新运行代码测试。pip install xlrd==1.2.0 - 指定替代引擎:若安装了
pyxlsb库,可指定引擎读取xls文件:df = pd.read_excel(filepath, engine='pyxlsb') - 生成xlrd诊断日志:用xlrd自带的日志功能定位问题,执行如下代码:
查看生成的日志文件,确认是哪个流导致的索引越界。import xlrd xlrd.open_workbook('./data/myfile.xls', logfile=open('xlrd_diagnose.log', 'w')) - 对比文件结构:用二进制对比工具,对比原xls文件和Excel重新保存后的xls文件的差异,明确结构上的区别。
是否为已知问题
这是xlrd项目中已被报告的已知问题,主要集中在2.x版本之后。xlrd 2.x移除了对xlsx格式的支持,同时调整了xls格式的解析逻辑,导致部分非标准xls文件出现解析错误。官方issue列表中有不少类似IndexError: array index out of range的报告,大多与复合文档的流解析逻辑相关。
内容的提问来源于stack exchange,提问作者phydev
相关产品推荐
相关产品推荐

