【问题标题】:Reading excel files with xlrd使用 xlrd 读取 excel 文件
【发布时间】:2012-09-24 04:56:36
【问题描述】:

我在读取由我无法控制的 Perl 脚本编写的 .xls 文件时遇到问题。这些文件在单元格中包含一些格式和换行符。

filename = '/home/shared/testfile.xls'
book = xlrd.open_workbook(filename)
sheet = book.sheet_by_index(0)
for rowIndex in xrange(1, sheet.nrows):
    row = sheet.row(rowIndex)

这会引发以下错误:

_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
172480= 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
172500  4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 3 2
172520  2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
173840= 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
173860  2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1
173880  1 1 1 1 1 1 1 1
Traceback (most recent call last):
  File "/home/shared/xlrdtest.py", line 5, in <module>
    book = xlrd.open_workbook(filename)
  File "/usr/local/lib/python2.7/site-packages/xlrd/__init__.py", line 443, in open_workbook
    ragged_rows=ragged_rows,
  File "/usr/local/lib/python2.7/site-packages/xlrd/book.py", line 84, in open_workbook_xls
    ragged_rows=ragged_rows,
  File "/usr/local/lib/python2.7/site-packages/xlrd/book.py", line 616, in biff2_8_load
    self.mem, self.base, self.stream_len = cd.locate_named_stream(qname)
  File "/usr/local/lib/python2.7/site-packages/xlrd/compdoc.py", line 393, in locate_named_stream
    d.tot_size, qname, d.DID+6)
  File "/usr/local/lib/python2.7/site-packages/xlrd/compdoc.py", line 421, in _locate_stream
    raise CompDocError("%s corruption: seen[%d] == %d" % (qname, s, self.seen[s]))
xlrd.compdoc.CompDocError: Workbook corruption: seen[2] == 4

我找不到任何有关 CompDocError 或 Workbook 损坏的信息,更不用说 see[2] == 4 部分。

【问题讨论】:

  • “文件名”包含什么?
  • 它只是一个文件路径,例如 'D:\\testfile.xls' 或 '/home/shared/testfile.xls' (更新问题)
  • @snurre,尝试将有问题的 xls 文件“附加”到这篇文章,这样错误就可以重现
  • 恐怕我做不到,因为它们包含机密信息。还应该注意的是,如果 xlrd 文件已经用 Excel 打开并保存,我可以加载它们,所以我怀疑这都与 Perl 脚本如何写入和保存文件有关。跨度>
  • 我是 xlrd 的作者。你运行的是什么版本的 xlrd?如果您不能根据保密协议向我发送您的 perl 编写文件的副本,那么最好的办法是告诉我您的电子邮件地址,以便我可以向您发送一个显示结构的调查脚本(不是文件的内容)。

标签: python excel xlrd


【解决方案1】:

[对于在读取 XLS 文件时遇到Workbook corruption: seen[2] == 4 问题的 pandas 用户]

注意: xlrd 不再支持 xls 文件以外的任何内容,请参阅 this answer 了解详细信息和替代方案。

  1. 使用xlrd 2.0.0 或更高版本:https://pypi.org/project/xlrd/

  2. 在自动加载的__init__.py 文件之一中添加您自己的熊猫XLS 引擎

from pandas.io.excel._xlrd import XlrdReader

class CustomXlrdReader(XlrdReader):

    def load_workbook(self, filepath_or_buffer):
        """Same as original, just uses ignore_workbook_corruption=True)"""
        from xlrd import open_workbook

        if hasattr(filepath_or_buffer, "read"):
            data = filepath_or_buffer.read()
            return open_workbook(file_contents=data, ignore_workbook_corruption=True)
        else:
            return open_workbook(filepath_or_buffer)


ExcelFile._engines['custom_xlrd'] = CustomXlrdReader
print('Monkey patching pandas XLS engines. See CustomXlrdReader')

要使用它,请在读取 XLS 文件时指定 engine='custom_xlrd'

df = pd.read_excel(filepath, engine='custom_xlrd')

这是测试xlrd 的损坏文件:

https://github.com/python-excel/xlrd/blob/master/tests/samples/corrupted_error.xls

【讨论】:

  • 错误:ignore_workbook_corruption=True 应该在两个分支中
【解决方案2】:

灵感来自this answer,但更直接一点:

pd.read_excel 接受 xlrd.Book 对象,因此您可以这样做:

workbook = xlrd.open_workbook('file_name.xls', ignore_workbook_corruption=True)
excel = pd.read_excel(workbook)

【讨论】:

    【解决方案3】:

    testfile.xls -----> 另存为 ---> 格式 97-2003 --->testfile2.xlc

    文件名 = '/home/shared/testfile2.xls'

    好的

    【讨论】:

    • 请详细说明您的答案。解释这是做什么的。
    【解决方案4】:

    来自 pkm 评论 (link) 的问题在于复合文件二进制文件

    #pip install OleFileIO-PL
    import OleFileIO_PL
    import pandas as pd
    
    path = 'file.xls'
    with open(path,'rb') as file:
        ole = OleFileIO_PL.OleFileIO(file)
        if ole.exists('Workbook'):
            d = ole.openstream('Workbook')
            x=pd.read_excel(d,engine='xlrd')
            print(x.head())
    

    【讨论】:

    【解决方案5】:

    +1 给拉米尔。 只需在compdoc.py 中注释掉这些行(xlrd 1.2.0 中的行425-27):

    if self.seen[s]:
        print("_locate_stream(%s): seen" % qname, file=self.logfile);dump_list(self.seen, 20, self.logfile)
        raise CompDocError("%s corruption: seen[%d] == %d" % (qname, s, self.seen[s]))
    

    【讨论】:

    • 我知道这是一个老问题,但是我遇到了同样的错误并注释掉那些行和那些提到here 但没有用的行。有人找到解决方案了吗?
    • @GustavoRottgering:见@holymoly345's answer
    【解决方案6】:

    我的一个 .xls 文件出现了同样的错误(excel 可以很好地打开它们)。问题位于 xlrd compdoc.py。我猜Compdoc.seen 数组会跟踪已读取的“FAT”扇区。在我的情况下,根条目读取块 (SSCS) 将所有扇区标记为已看到,从而导致将来引发异常。您可以尝试在读取逻辑的扇区中找到错误并为 xlrd 做出贡献 :) 或仅使用异常 raise 评论此行,这可能会解决您的问题(就像我的一样)并等待 xlrd 更新。

    【讨论】:

      【解决方案7】:

      也许作为最后的手段,您可以尝试将 .xls 文件保存为 .csv 文件,然后尝试读取它。

      显然你说你可以在从 Excel 中打开和关闭后打开它,所以这是同样的努力。

      如果您真的希望您的脚本打开它们,那么如果您在 Windows 平台上,请使用pywin32 从您的脚本中打开和关闭 Excel,然后同时打开和关闭文件。也许这可以工作。 (愚蠢但可以解决)

      示例 (stolen from here)

      from win32com.client import Dispatch
      xl = Dispatch('Excel.Application')
      wb = xl.Workbooks.Open('C:\\Documents and Settings\\GradeBook.xls')
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-14
        • 2021-05-03
        • 1970-01-01
        • 2020-09-15
        • 2021-02-02
        • 1970-01-01
        • 1970-01-01
        • 2021-10-28
        相关资源
        最近更新 更多