前言
工作中经常会遇到Excel
加密的情况,用Python
来读取时常用的xlrd
库无法对这类文件进行读取。在网上搜索对这类问题的处理后,发现常用的pywin32
包中的win32com.client.DispatchEx
方法也无效,最终采取了一种“曲线救国”的思路,这里记录一下。
问题描述
遇到的Excel
文件满足以下情况:
1. 文件扩展名为.xlsx
;
2. 当文件打开时弹出一个输入密码的对话框;
3. 当第一次输入密码后,在Excel
打开后,又第二次显示要输入密码的对话框;
4. 文件密码已知。
遇到的第一个对话框如下: 当输入密码后,遇到的第二 个对话框如下: 观察上述两个对话框,会发现第一个对话框中的文件名是正常的,是原文件本来的名称,而第二个对话框中的文件名却变成了一个临时文件名,且提示将要打开的文件是“只读”属性。 注意: 本机安装的是MsOffice2003
及
office2007兼容包
。
利用win32com.client
对问题的探索
在网络上有许多关于利用win32com.client
进行打开加密excel
的例子,其打开并读取数据的代码如下:
import win32com.clientxlApp = win32com.client.DispatchEx("Excel.Application")xlwb = xlApp.Workbooks.Open(filename, False, True, None, Password=password)# 获取行数rows=xlwb.Worksheets(1).UsedRange.Rows.Count# 获取列数col=xlwb.Worksheets(1).UsedRange.Columns.Count#数据遍历重新写出df_list=[] for i in range(rows+1): #每一行的值加入一个list df_row_list=[] for j in range(col+1): #获取每个单元格的值 a=xlwb.Worksheets(1).Cells(i+1,j+1).Value df_row_list.append(a) df_list.append(df_row_list)
这里的
win32com.client
属于
Python
的第三方包
Pywin32
中所有,上述代码对于我们自己设置密码的文件可以打开,设置两步打步打开的加密如下图所示:
用上述代码打开自己加密的文件没有问题,可以正常读取,但在读取我们的目标文件时,始终提示无法打开的错误,未找到原因何在。
“曲线救国”的msoffcrypto-tool
在利用
pywin32
无法解决问题后,另一个思路即是对该文件进行解密,这样就可以利用
xlrd
对解密后的文件进行读取,问题在于如何解密呢?
事实上,在
Python
的第三方库中有一个强大的专门针对
Ms Office
文件进行解密的第三方包:
msoffcrypto-tool
,安装该包很容易:
pip install msoffcrypto-tool
然后导入该包,加载文件和密码,并生成解密后的文件,代码如下:
import msoffcryptofiletmp = msoffcrypto.OfficeFile(open(filename, 'rb'))filetmp.load_key(password=password)filetmp.decrypt(open(newxlsfilename, 'wb'))
成功运行该段代码后,解密的文件即为newxlsfilename
,这里要注意的是,由于原文件扩展名是xlsx
,最好将解密后的文件以xlsx
为扩展名进行命名,否则解密的文件会有问题,另外,最好将生成的新文件与原文件区分开来,不要直接做替换,否则会将原文件损坏。
xlrd
对解密后的文件
newxlsfilename
进行读取即可。
小结
本文对如何利用Python
读取加密的
Excel
文档进行了分析,在实际的操作过程中,如果一条路不通的时候,换一种思路往往能起到较好的作用。