如何加载 Python 一个原本有 .xls 文件扩展名的 xlsx?

How to load in Python an xlsx that originally had .xls file extension?

我正在使用 xlrd 处理 .xls 文件,并使用 openpyxl 处理 .xlsx 文件,这运行良好。

然后我收到了一个表面上是 .xls 文件的文件,所以我尝试 xlrd.open_workbook(),并得到:

XLRDError: Unsupported format, or corrupt file: Expected BOF record; found '<?xml ve'

我查看了 this 问题,我推测我的文件虽然以扩展名 .xls 结尾,但实际上必须是 .xlsx。事实上,我可以在文本编辑器中查看它:

<?xml version="1.0" encoding="UTF-8"?>
                      <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
                       xmlns:x="urn:schemas-microsoft-com:office:excel"
                       xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
                       xmlns:html="http://www.w3.org/TR/REC-html40">
:
:
:

(出于隐私原因,我不能 post 整个文件,但我们的分析可能不需要它)。

所以我推测如果我只是将它复制 (cp) 到 .xlsx,我应该可以用 openpyxl.load_workbook() 打开它,但我得到:

BadZipfile: File is not a zip file

如果它实际上是一个 xls(不太可能)但不能用 xlrd 打开,如果它实际上是一个 xlsx 但不能用 openpyxl 打开,即使我 cp 它到一个 .xlsx,怎么办?

注意:如果我在 Excel 中打开 .xls,将其另存为 .xlsx,然后使用 openpyxl 重试,加载正常,但本手册在执行我的程序时,这一步不是奢侈。

有一点很清楚:您尝试打开的文件的格式与其扩展名建议的格式不同。

如您所知,Excel 文件格式包括(但不限于)xlsxlsx.

  • Excel 2003 格式 (xls) 是一种二进制格式。这意味着如果您使用文本编辑器打开 xls 文件,您只会看到乱码。

  • Excel 2007 格式 (xlsx) 完全不同。 xlsx 文件是一个 zip 文件,里面有一堆 XML 文件。您可以使用 zip 存档器来提取 xlsx 文件的内容。然后,您可以使用任何文本编辑器编辑 XML 文件。但是,直接用文本编辑器打开 xlsx 文件就像用文本编辑器打开 zip 文件一样:您只会看到乱码。

可以 使用文本编辑器打开文件(并阅读其内容)这一事实表明它既不是 xls 文件也不是 xlsx 文件。您的文件既不是二进制文件也不是 zip 文件,它是 plain XML 文件。

此外,这个错误消息说明了很多。

BadZipfile: File is not a zip file

这意味着 openpyxl 正在尝试将您的文件作为 xlsx 文件打开,因此是 zip 文件。但是当它试图提取其内容时,它失败了,因为您的文件甚至不是 zip 文件。

但是如果文件既不是xlsx文件也不是xls文件,微软Excel如何读取它?我也想知道。经过一些研究,我相信您的文件 XML Spreadsheet 2003 file format. This example 看起来与您发布的文件内容非常相似。既然微软Excel支持这种格式,难怪它能读取你的文件。

不幸的是,Python 库,例如 xlrdopenpyxl 仅支持 xlsxlsx 文件格式,因此它们将无法阅读你的文件。我认为您只需要手动将其转换为受支持的格式即可。

我不在OSX,所以这个没有测试。尽管缺少支持,您也许可以使用 appscript 包来打开有问题的文件并重新保存它。

from appscript import *
excel = app('Microsoft Excel')
wb = excel.open('/path/to/file.xls')
wb.save_as('/path/to/fileout.xlsx', file_format=k.XLSX_file_format)
#not sure the exact name of k.excel_file

我遇到了类似的问题。原来它需要绝对文件路径。例如,"c:/dir/filename.xlsx" 而不是 "filename.xlsx"。相对路径适用于 osx,但不适用于 Windows。