是否有可能从zipfile加载xpyx与openpyxl

我试图从压缩的zip文件openpyxl.load_workbook xlsx文件,但它不起作用。 下面的代码失败在openpyxl.load_workbook“BadZipfile:文件不是一个zip文件”

with zipfile.ZipFile(os.path.join(root, raw)) as z: for file_info in z.infolist(): wb = openpyxl.load_workbook(z.open(file_info), read_only=True) 

存档和其中的excel文件没有什么问题,就好像我把它解压缩到磁盘那么下面的工作:

 with open('report.xlsx') as f: wb = openpyxl.load_workbook(f, read_only=True) 

我可以使用这个解决scheme,并临时解压到某处并加载xslx,但想知道是否可以从zipfile加载它。

问题是readonly=True并不完全符合你的想法。 根据文件 :

幸运的是,有两种模式使您可以读取和写入无限量的数据(接近)不变的内存消耗。

虽然没有明确说明,但我认为这涉及一些等效于内存映射文件(由于“恒定内存消耗”)和随机访问(由于允许的操作范围)。

无论哪种方式,设置readonly=True并不意味着你只打算读取一个工作簿(这是所有的load_workbook可以做的,你必须覆盖现有的做任何“改变”)。 这表示您希望直接在磁盘上访问该文件,而无需加载整个内容。

看起来相当清楚(并且直观的预期), ZipFile.open不提供随机访问文件:

注意:文件类对象是只读的,并提供以下方法: read()readline()readlines()__iter__()next()

这个名单中没有提到seek的事实是相当有说服力(双关语只是有点意图)。

通过将违规行分为两行(嵌套函数调用的一个有用的通用debugging技术),可以获得有关exception的更多信息:

 x = z.open(file_info) wb = openpyxl.load_workbook(x, readonly=True) 

您会注意到这两行中的第二行发生错误。 这是因为几乎所有的微软公开文档格式实际上都只是很好的zip文件。 问题很可能是openpyxl无法以随机存取模式打开您的文件,而不是它实际上是一个无效的zip文件。

无论哪种方式,这是一个非常教育的猜测导致一个简单的,一个关键字删除解决scheme:

TL; DR

阅读非随机访问数据(如压缩的zip条目)时,请删除readonly=True

 wb = openpyxl.load_workbook(z.open(file_info)) 

附录

你应该养成编写最小程序的习惯来certificate你的问题,这样回答你问题的人就可以把精力集中在做自己的工作上,而不是被激怒,关掉那些本来是一个很好的问题。 我喜欢你的问题,足以为你做到这一点,所以这里是一个最小的程序,它演示了你的问题,只需要复制和粘贴即可运行:

 import openpyxl, zipfile from openpyxl.workbook.workbook import Workbook wb = Workbook() wb.active['A1'] = 12 wb.active['A2'] = 13 wb.save('report.xlsx') with zipfile.ZipFile('test.zip', 'w') as z: z.write('report.xlsx') with open('report.xlsx') as f: wb = openpyxl.load_workbook(f, read_only=True) print(wb.active['A1'].value) print(wb.active['A2'].value) with zipfile.ZipFile('test.zip', 'r') as z: for file_info in z.infolist(): x = z.open(file_info, 'r') wb = openpyxl.load_workbook(x, readonly=True) print(wb.active['A1'].value) print(wb.active['A2'].value)