0x80070570文件或目录损坏且无法读取_Python如何读取加密的Excel文档

前言

工作中经常会遇到Excel加密的情况,用Python来读取时常用的xlrd库无法对这类文件进行读取。在网上搜索对这类问题的处理后,发现常用的pywin32包中的win32com.client.DispatchEx方法也无效,最终采取了一种“曲线救国”的思路,这里记录一下。

问题描述

遇到的 Excel 文件满足以下情况:

1. 文件扩展名为.xlsx;

2. 当文件打开时弹出一个输入密码的对话框;

3. 当第一次输入密码后,在Excel打开后,又第二次显示要输入密码的对话框;

4. 文件密码已知。

遇到的第一个对话框如下:

218baa9c387384c92f5ec6329de0e168.png

当输入密码后,遇到的第二 个对话框如下:

984e3654c04937627b1b452007185b85.png

观察上述两个对话框,会发现第一个对话框中的文件名是正常的,是原文件本来的名称,而第二个对话框中的文件名却变成了一个临时文件名,且提示将要打开的文件是“只读”属性。 注意: 本机安装的是 MsOffice2003office2007兼容包

利用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 中所有,上述代码对于我们自己设置密码的文件可以打开,设置两步打步打开的加密如下图所示:

f313f1cd24d767c214c8a5b0e275b1b9.png

用上述代码打开自己加密的文件没有问题,可以正常读取,但在读取我们的目标文件时,始终提示无法打开的错误,未找到原因何在。

“曲线救国”的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 文档进行了分析,在实际的操作过程中,如果一条路不通的时候,换一种思路往往能起到较好的作用。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值