他们用什么来生成该文件?
他们正在使用一些Java Excel API(请参见下面的链接 ),可能在IBM大型机或类似主机上。
由于@字符,无法从堆栈跟踪中将writeaccess信息解码为Unicode。
有关XLS文件格式的writeaccess信息的更多信息,请参见5.112 WRITEACCESS或第277页 。
此字段包含已保存文件的用户的用户名。
import xlrd
dump = xlrd.dump('thefile.xls')
在原始文件上运行xlrd.dump给出
36: 005c WRITEACCESS len = 0070 (112)
40: d1 81 a5 81 40 c5 a7 83 85 93 40 c1 d7 c9 40 40 ????@?????@???@@
56: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 @@@@@@@@@@@@@@@@
72: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 @@@@@@@@@@@@@@@@
88: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 @@@@@@@@@@@@@@@@
104: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 @@@@@@@@@@@@@@@@
120: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 @@@@@@@@@@@@@@@@
136: 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 40 @@@@@@@@@@@@@@@@
用Excel或我的情况下的LibreOffice Calc重新保存后,写访问信息被类似以下内容覆盖
36: 005c WRITEACCESS len = 0070 (112)
40: 04 00 00 43 61 6c 63 20 20 20 20 20 20 20 20 20 ?~~Calc
56: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
72: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
88: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
104: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
136: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
基于被编码为40的空格,我相信编码是EBCDIC,当我们将d1 81 a5 81 40 c5 a7 83 85 93 40 c1 d7 c9 40 40为EBCDIC时,我们得到了Java Excel API 。
因此,是的,在BIFF8及更高版本的情况下,文件被错误地写入,它应该是unicode字符串,而在BIFF3至BIFF5中,它应该是CODEPAGE信息中编码的字节字符串。
152: 0042 CODEPAGE len = 0002 (2)
156: 12 52 ?R
1252是Windows CP-1252(拉丁文I)(BIFF4-BIFF5),不是EBCDIC_037 。
xlrd尝试使用unicode的事实意味着它确定文件的版本为BIFF8。
在这种情况下,您有两个选择
在使用xlrd打开文件之前先对其进行修复。 您可以检查是否使用转储到不是标准输出的文件,如果是这种情况,则可以使用xlutils.save或其他库覆盖writeaccess信息。
修补xlrd以处理您的特殊情况,在handle_writeaccess添加一个try块,并在unpack_unicode失败时将strg设置为空字符串。
以下代码段
def handle_writeaccess(self, data):
DEBUG = 0
if self.biff_version < 80:
if not self.encoding:
self.raw_user_name = True
self.user_name = data
return
strg = unpack_string(data, 0, self.encoding, lenlen=1)
else:
try:
strg = unpack_unicode(data, 0, lenlen=2)
except:
strg = ""
if DEBUG: fprintf(self.logfile, "WRITEACCESS: %d bytes; raw=%s %r\n", len(data), self.raw_user_name, strg)
strg = strg.rstrip()
self.user_name = strg
与
workbook=xlrd.open_workbook('thefile.xls',encoding_override="cp1252")
似乎已成功打开文件。
如果没有编码覆盖,它将抱怨ERROR *** codepage 21010 -> encoding 'unknown_codepage_21010' -> LookupError: unknown encoding: unknown_codepage_21010