我正在尝试从压缩的zip文件中打开openxxl.load_workbook xlsx文件,但它不起作用。以下代码在openpyxl.load_workbook中失败并显示“BadZipfile:File is not a zip file”
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)
我可以使用此解决方案并临时解压缩并加载xslx,但是想了解是否可以从zipfile加载它。
答案 0 :(得分:4)
问题在于readonly=True
没有做到你认为的那样。根据{{3}}:
幸运的是,有两种模式可以让您在(接近)恒定内存消耗的情况下读取和写入无限量的数据。
虽然没有明确说明,但我认为这涉及一些等同于内存映射文件(因为"常量内存消耗")和随机访问(因为允许操作的范围)。 / p>
无论哪种方式,设置readonly=True
并不表示您只打算阅读工作簿(无论如何load_workbook
都可以执行,您必须覆盖现有工作簿进行任何改变")。这表明您希望直接在磁盘上访问该文件,而无需加载整个内容。
似乎很清楚(并且直观地预期)docs不提供随机访问文件:
注意:类似文件的对象是只读的,并提供以下方法:
read()
,readline()
,readlines()
,__iter__()
,next()
。
此列表中未提及seek
的事实非常明显(双关语只是有点意图)。
您可以通过将有问题的行拆分为两个来获得有关异常的更多信息(对于嵌套函数调用,这是一种有用的常规调试技术):
x = z.open(file_info)
wb = openpyxl.load_workbook(x, readonly=True)
您会注意到这两行中的第二行发生错误。这是因为几乎所有的Microsoft开放文档格式实际上只是花哨的zip文件。问题很可能是openpyxl无法以随机访问模式打开您的文件,而不是它实际上是无效的zip文件。
无论哪种方式,这是一堆非常有根据的猜测,导致一个简单的,一个关键字删除解决方案:
在读取非压缩zip条目等非随机访问数据时删除readonly=True
:
wb = openpyxl.load_workbook(z.open(file_info))
你应该养成写出能够证明你的问题的最小程序的习惯,以便回答你问题的人可以集中精力完成自己的工作,而不是烦恼并关闭本来是一个非常好的问题。我喜欢你的问题足以为你做到这一点,所以这里有一个最小的程序来演示你的问题,只需复制并粘贴即可运行:
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)