问题描述
我有一个简短的程序,该程序收集文件夹/子文件夹中所有.xls文件的列表,然后循环浏览文件列表,打开每个xls文档(尝试:book = xlrd.open_workbook(f))以查找有关特定信息.如果抛出异常,我将文件名写到异常列表中.我发现我有很多xlrd引发错误的文件:
I have a short program that collects a list of all .xls files in folder/sub-folders and then I loop through the file list, opening each xls document (Try: book = xlrd.open_workbook(f) ) to look for specific information. If an exception is thrown, I write out the filename to an exception list. What I am finding is that I have a LOT of files that xlrd throws the error :
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
book = xlrd.open_workbook(f)
File "C:\Python32\lib\site-packages\xlrd\__init__.py", line 435, in open_workbook
ragged_rows=ragged_rows,
File "C:\Python32\lib\site-packages\xlrd\book.py", line 116, in open_workbook_xls
bk.parse_globals()
File "C:\Python32\lib\site-packages\xlrd\book.py", line 1206, in parse_globals
self.handle_filepass(data)
File "C:\Python32\lib\site-packages\xlrd\book.py", line 924, in handle_filepass
raise XLRDError("Workbook is encrypted")
xlrd.biffh.XLRDError: Workbook is encrypted
但是我可以使用Excel毫无问题地打开文件.有谁知道为什么xlrd在文件似乎没有加密的情况下会引发加密错误?
But I can go and open the files with Excel with no problems. Does anyone have an idea as to why xlrd would throw an encrypted error when it doesn't appear that the files are encrypted?
谢谢
弗雷德
推荐答案
我遇到了同样的问题,正如@zindorsky在其评论中提到的那样,当文件具有受保护的工作表时可能会发生这种情况-或由于其他原因Excel已使用魔术密码VelvetSweatshop
静默加密了文件.
I ran into this same problem, and as @zindorsky has mentioned in their comment, this can happen when the file has a protected sheet - or via some other reason where Excel has silently encrypted the file with the magic password VelvetSweatshop
.
XLRD无法单独处理带有加密的文件(实际上,自述文件将其列为不太可能完成"),但是最近又有一个Python库可以解密各种MS Office文件(包括.xls文件)- msoffcrypto-tool .
XLRD can't handle files with encryption on its own (in fact the README lists it as 'unlikely to be done'), but there is another recent Python library that can unencrypt a variety of MS Office files (including .xls files) - msoffcrypto-tool .
我能够使用它成功解决此问题-这是该代码的缩写(未经测试!)片段
I was able to use it to workaround the issue successfully - here's an abbreviated (and untested!) snippet version of the code
import xlrd
import msoffcrypto
def handle_protected_workbook(wb_filepath):
try:
_book = xlrd.open_workbook(wb_filepath)
except xlrd.biffh.XLRDError, e:
if e.message == "Workbook is encrypted":
# Try and unencrypt workbook with magic password
wb_msoffcrypto_file = msoffcrypto.OfficeFile(open(wb_filepath, 'rb'))
try:
# Yes, this is actually a thing
# https://nakedsecurity.sophos.com/2013/04/11/password-excel-velvet-sweatshop/
wb_msoffcrypto_file.load_key(password='VelvetSweatshop')
except AssertionError, e:
if e.message == "Failed to verify password":
# Encrypted with some other password
raise # or do something else
else:
# Some other error occurred
raise
except:
# Some other error occurred
raise
else:
# Magic Excel password worked
assert wb_filepath.endswith('.xls')
wb_unencrypted_filename = wb_filepath[:-(len('.xls'))] + '__unencrypted.xls'
with tempfile.NamedTemporaryFile() as tmp_wb_unencrypted_file:
# Decrypt into the tempfile
wb_msoffcrypto_file.decrypt(tmp_wb_unencrypted_file)
# --- Do something with the file ---
# return true to indicate file was touched
return True # or do something else
else:
# some other xlrd error occurred.
return False # or do something else
except:
# some non-xlrd error occurred.
return False # or do something else
这篇关于xlrd-错误“工作簿已加密",Python 3.2.3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!