python xlrd 旧xls文件错误

1 投票
1 回答
1340 浏览
提问于 2025-04-18 05:57

我有一个Excel文件,是用一些比较老的软件创建的。这个文件在OpenOffice里打不开(出现了一些编码错误),而在Excel 2010里一开始只能在保护视图中打开。

当我尝试用xlrd打开它时:

from xlrd import open_workbook
rb = open_workbook('405_mut_1x.xls', encoding_override="utf-8")

我遇到了一个错误:

Traceback (most recent call last):
  File "/home/wintr/PycharmProjects/4lab_1/main.py", line 2, in <module>
    rb = open_workbook('405_mut_1x.xls', encoding_override="utf-8")
  File "/usr/lib/python3/dist-packages/xlrd/__init__.py", line 435, in open_workbook
    ragged_rows=ragged_rows,
  File "/usr/lib/python3/dist-packages/xlrd/book.py", line 107, in open_workbook_xls
    bk.fake_globals_get_sheet()
  File "/usr/lib/python3/dist-packages/xlrd/book.py", line 714, in fake_globals_get_sheet
    self.get_sheets()
  File "/usr/lib/python3/dist-packages/xlrd/book.py", line 705, in get_sheets
    self.get_sheet(sheetno)
  File "/usr/lib/python3/dist-packages/xlrd/book.py", line 696, in get_sheet
    sh.read(self)
  File "/usr/lib/python3/dist-packages/xlrd/sheet.py", line 1467, in read
    self.update_cooked_mag_factors()
  File "/usr/lib/python3/dist-packages/xlrd/sheet.py", line 1535, in update_cooked_mag_factors
    elif not (10 <= zoom <= 400):
TypeError: unorderable types: int() <= NoneType()

尝试用cp1252、utf-7和utf_16_le这些编码方式,跟其他类似问题里建议的一样,结果也是一样的。

ERROR *** codepage None -> encoding 'utf_16_le' -> UnicodeDecodeError: 'utf16' codec can't decode byte 0x6c in position 4: truncated data

如果不指定编码,我在错误追踪中看到了一些额外的字符串。

*** No CODEPAGE record, no encoding_override: will use 'ascii'

后来我在Excel 2010中把文件保存为xlsx格式后,这个问题就消失了——文件可以在xlrd和OpenOffice中都打开。请问有没有办法在不重新保存的情况下,用xlrd打开这样的文件?

更新:在python2.7的xlrd中没有这个问题。不过我还是不知道python3.3的xlrd出了什么问题。

1 个回答

0

这个问题是因为Python 2和Python 3在某些地方的表现不一样:

$ python2
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 <= None
False

$ python3
Python 3.4.3 (default, Jul 28 2015, 18:20:59) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 <= None
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: int() <= NoneType()

要解决这个问题,你可以在xlrd/sheet.py文件的第1543行附近进行修改:

elif not (10 <= zoom <= 400):

改成

elif zoom is None or not (10 <= zoom <= 400):

这样的话,行为就会和Python 2一样了。

撰写回答