16

我在读取由我无法控制的 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 部分。

4

7 回答 7

10

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

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]))
于 2016-02-05T04:06:48.160 回答
8

从 pkm 评论(链接)中,问题出在复合文件二进制文件上

#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())
于 2020-02-26T14:25:39.150 回答
7

Workbook corruption: seen[2] == 4[对于阅读XLS文件时遇到问题的熊猫用户]

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

  1. 使用xlrd2.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')

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

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

xlrd是测试的损坏文件:

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

于 2020-12-11T16:13:17.907 回答
5

受此答案的启发,但更直截了当:

pd.read_excel 接受 xlrd.Book 对象,所以你可以这样做:

workbook = xlrd.open_workbook('file_name.xls', ignore_workbook_corruption=True)
excel = pd.read_excel(workbook)
于 2021-04-21T11:38:57.553 回答
2

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

于 2013-11-15T09:05:15.810 回答
0

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

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

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

例子(从这里偷来的

from win32com.client import Dispatch
xl = Dispatch('Excel.Application')
wb = xl.Workbooks.Open('C:\\Documents and Settings\\GradeBook.xls')
于 2012-10-03T18:41:36.427 回答
-1

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

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

好的

于 2020-10-26T07:39:13.850 回答