python - How to unlock a password protected excel file using R and VBA
问题描述
I have some password protected files received from my colleagues on a daily basis and I would like to unlock them programmatically so that I can read them do build my reports.
In Python I was able to unlock files with the win32com.client
default package. How about R?
Here's how I did it in Python,
def unprotect_xlsx(filename, pwd):
try:
xcl = win32com.client.Dispatch('Excel.Application')
wb = xcl.Workbooks.Open(filename, False, False, None, pwd)
wb.Unprotect(pwd)
wb.UnprotectSharing(pwd)
xcl.DisplayAlerts = False
wb.SaveAs(filename.split('.xlsx')[0]+"_unlocked"+".xlsx", None, '', '')
xcl.Quit()
except Exception as e:
print("Error:")
print(e)
解决方案
However, if you are using R, you must have come acroos this RDCOMClient
library but it is merely an interface to work with a variety of clients without exactly having a built-in function that can do the unlocking.
So I had a workaround. I used RDCOMClient
to interface with an macro-enabled excel VBA file which does the unlocking.
I created the macro-enabled excel (macro_unlocker.xlsm), enabled the developer option and wrote this VBA code which will take in the filename and password from R and unlock the file as an Excel program,
Public Sub unlock_file(filename, pwd)
Dim wb As Workbook
Dim filename_path As String
filename_path = filename
'MsgBox filename_path & " " & pwd
Set wb = Workbooks.Open(filename:=filename, Password:=pwd)
save_filepath = Split(filename, ".xlsx")(0) & "_unlocked.xlsx"
wb.SaveAs filename:=save_filepath, Password:=""
End Sub
The RDCOMClient
interfaces with the VBA by passing the arguments to the VBA script. It unlocked the file by setting the password as an empty string.
Then in R, I can write a function to pass the arguments to it. And this is what I have, I put this in an external R file called myUtils.R
just to make things neater,
unlock_xlsx <- function(filename, pwd){
if (!require("pacman")) install.packages("pacman")
pacman::p_load(devtools)
devtools::install_github("dkyleward/RDCOMClient")
library(RDCOMClient)
# Open a specific workbook in Excel:
xlApp <- COMCreate("Excel.Application")
xlWbk <- xlApp$Workbooks()
xlWbk$Open(paste(getwd(), "/<utils folder>/macro_unlocker.xlsm",sep=""))
# this line of code might be necessary if you want to see your spreadsheet:
xlApp[['Visible']] <- TRUE
# Run the macro:
xlApp$Run("unlock_file", filename, pwd)
# Close the workbook and quit the app:
xlWbk$Close(FALSE)
xlApp$Quit()
}
So finally to run the functions and the VBA macro in R so that I can unlock the files programmatically and do my work I wrote this in R,
# call in myUtils.R where the function unlock_xlsx resides
source(paste(getwd(), "./myUtils.R", sep=""))
# file to unlock
password_locked_file_FILEPATH <- Sys.glob(file.path("<sub-folder>", "<sub-folder>","<an_excel.xlsx>"))
# send the file_filepath to the function
file_to_unlock <- paste("../", password_locked_file_FILEPATH, sep="")
password_locked_file_pwd <- "<password>"
# result will be suffixed with '_unlocked' followed by '.xlsx'
unlock_xlsx(filename = file_to_unlock, pwd = password_locked_file_pwd)
Tada! The file is unlocked and saved with the suffix _unlocked
. And you can definitely cycle through your files to be unlocked and provide the corresponding passwords and everything would work like clockwork.
This works as long you have R and Excel installed in your machine.
Note: I do understand there are some issues with the installation of RDCOMClient
its not compatible with the latest R version 3.6. I had a workaround by installing dkyleward/RDCOMClient
and it installed perfectly well on a Windows machine but failed on MacOS.
推荐阅读
- jquery - 在无序列表中动态设置排序
- ms-access - 如何在 MS Access 表单的不同表中显示基于不同值的值?
- linq - 来自行不同的两个列表的 Linq 查询过滤器
- c# - 查询 RavenDb 文档中的嵌套集合
- paxos - Paxos:如何选择提议者、接受者和学习者?
- javascript - 仅使用 DIV 在 JavaScript 中制作时钟
- neo4j - Neo4j:更新现有节点之间的关系
- android - ARCore 1.2 Unity 即时创建 AugmentedImageDatabase
- ios - 解析服务器每次保存时都会创建一个新条目
- php - 尝试使 PDO 执行工作时出错