使用 pandas read_excel() 将 .xls 文件格式导入 python 时出现 CompDocError

Posted

技术标签:

【中文标题】使用 pandas read_excel() 将 .xls 文件格式导入 python 时出现 CompDocError【英文标题】:CompDocError when importing .xls file format to python using pandas read_excel() 【发布时间】:2020-02-08 16:37:54 【问题描述】:

我正在尝试导入 IMF 的 GDP 数据。它是一个扩展名为 .xls 格式的 excel 文件。 当我尝试使用以下代码导入它时:

imf_data = pd.read_excel('C:\\Users\\amir\\Downloads\\imf_data.xls', sheet_name=None)

我收到以下错误:

_locate_stream(Workbook): seen
    0  5 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
   20  4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
  340= 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
  360  4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 2 
  380  2 2 
---------------------------------------------------------------------------
CompDocError                              Traceback (most recent call last)
<ipython-input-6-784f71031ca1> in <module>
----> 1 imf_data = pd.read_excel('C:\\Users\\amir\\Downloads\\imf_data.xls', sheet_name=None)

~\Anaconda3\lib\site-packages\pandas\util\_decorators.py in wrapper(*args, **kwargs)
    186                 else:
    187                     kwargs[new_arg_name] = new_arg_value
--> 188             return func(*args, **kwargs)
    189         return wrapper
    190     return _deprecate_kwarg

~\Anaconda3\lib\site-packages\pandas\util\_decorators.py in wrapper(*args, **kwargs)
    186                 else:
    187                     kwargs[new_arg_name] = new_arg_value
--> 188             return func(*args, **kwargs)
    189         return wrapper
    190     return _deprecate_kwarg

~\Anaconda3\lib\site-packages\pandas\io\excel.py in read_excel(io, sheet_name, header, names, index_col, parse_cols, usecols, squeeze, dtype, engine, converters, true_values, false_values, skiprows, nrows, na_values, keep_default_na, verbose, parse_dates, date_parser, thousands, comment, skip_footer, skipfooter, convert_float, mangle_dupe_cols, **kwds)
    348 
    349     if not isinstance(io, ExcelFile):
--> 350         io = ExcelFile(io, engine=engine)
    351 
    352     return io.parse(

~\Anaconda3\lib\site-packages\pandas\io\excel.py in __init__(self, io, engine)
    651         self._io = _stringify_path(io)
    652 
--> 653         self._reader = self._engines[engine](self._io)
    654 
    655     def __fspath__(self):

~\Anaconda3\lib\site-packages\pandas\io\excel.py in __init__(self, filepath_or_buffer)
    422             self.book = xlrd.open_workbook(file_contents=data)
    423         elif isinstance(filepath_or_buffer, compat.string_types):
--> 424             self.book = xlrd.open_workbook(filepath_or_buffer)
    425         else:
    426             raise ValueError('Must explicitly set engine if not passing in'

~\Anaconda3\lib\site-packages\xlrd\__init__.py in open_workbook(filename, logfile, verbosity, use_mmap, file_contents, encoding_override, formatting_info, on_demand, ragged_rows)
    155         formatting_info=formatting_info,
    156         on_demand=on_demand,
--> 157         ragged_rows=ragged_rows,
    158     )
    159     return bk

~\Anaconda3\lib\site-packages\xlrd\book.py in open_workbook_xls(filename, logfile, verbosity, use_mmap, file_contents, encoding_override, formatting_info, on_demand, ragged_rows)
     86             formatting_info=formatting_info,
     87             on_demand=on_demand,
---> 88             ragged_rows=ragged_rows,
     89         )
     90         t1 = perf_counter()

~\Anaconda3\lib\site-packages\xlrd\book.py in biff2_8_load(self, filename, file_contents, logfile, verbosity, use_mmap, encoding_override, formatting_info, on_demand, ragged_rows)
    634                 for qname in ['Workbook', 'Book']:
    635                     self.mem, self.base, self.stream_len = \
--> 636                                 cd.locate_named_stream(UNICODE_LITERAL(qname))
    637                     if self.mem: break
    638                 else:

~\Anaconda3\lib\site-packages\xlrd\compdoc.py in locate_named_stream(self, qname)
    397             result = self._locate_stream(
    398                 self.mem, 512, self.SAT, self.sec_size, d.first_SID,
--> 399                 d.tot_size, qname, d.DID+6)
    400             if self.DEBUG:
    401                 print("\nseen", file=self.logfile)

~\Anaconda3\lib\site-packages\xlrd\compdoc.py in _locate_stream(self, mem, base, sat, sec_size, start_sid, expected_stream_size, qname, seen_id)
    425             if self.seen[s]:
    426                 print("_locate_stream(%s): seen" % qname, file=self.logfile); dump_list(self.seen, 20, self.logfile)
--> 427                 raise CompDocError("%s corruption: seen[%d] == %d" % (qname, s, self.seen[s]))
    428             self.seen[s] = seen_id
    429             tot_found += 1

CompDocError: Workbook corruption: seen[2] == 4

为什么会发生这样的事情以及如何解决?

【问题讨论】:

您可以尝试将文件另存为 XLSX 文件吗?即,采用较新的 OOXML 格式。然后使用 pandas 重试读取文件。 @JustinEzequiel 我还没有尝试过。我刚刚下载了文件并尝试使用 pd.read_csv 打开它。让我试试。我会回复你的。 基于他的:***.com/questions/49197793/…,它可能不是真正的 xls 文件,您的文件看起来像:***.com/questions/12705527/… 【参考方案1】:

在我的例子中,它是一个带有 .xls 扩展名的 Compound Document format。

我们可以使用 OleFileIO_PL 包在 Python 中打开这些文件。 我的真实例子:

import pandas as pd
import requests
import OleFileIO_PL

url = "https://www.cepea.esalq.usp.br/br/indicador/series/milho.aspx?id=77"
resp = requests.get(url)
ole = OleFileIO_PL.OleFileIO(resp.content)
df = pd.read_excel(ole.openstream('Workbook'), skiprows=3)

【讨论】:

以上是关于使用 pandas read_excel() 将 .xls 文件格式导入 python 时出现 CompDocError的主要内容,如果未能解决你的问题,请参考以下文章

请问在Pandas用read_excel函数读取数据

pandas read_excel,将单个标题读取到多列

Pandas 高级 read_excel 或 ExcelFile.parse

pandas.read_excel,第一行值

编码参数是不是适用于 pandas.read_excel?

无法使用 pandas.read_excel 访问 .xlsx 文件中的数据