I am trying to generate a password protected Excel file consisting of multiple sheets using R. I have tried different solutions, but none have been satisfactory.
Below a reproducible example:
library(excel.link)
library(openxlsx)
# Create some sample data
df1 <- data.frame(A = 1:5, B = letters[1:5])
df2 <- data.frame(X = 10:14, Y = LETTERS[10:14])
# Create a multi-sheet Excel file
wb <- createWorkbook()
addWorksheet(wb, "Sheet1")
addWorksheet(wb, "Sheet2")
writeData(wb, "Sheet1", df1)
writeData(wb, "Sheet2", df2)
# Save the file
file_name <- "test.xlsx"
saveWorkbook(wb, file_name,
overwrite = TRUE) # saved multi-sheet file without password protection
# Use excel.link to save a password protected file
excel.link::xl.save.file(r.obj = list(df1 = df1, df2 = df2),
filename = "protected.xlsx",
password = "password") # saved single-sheet protected file
I am trying to generate a password protected Excel file consisting of multiple sheets using R. I have tried different solutions, but none have been satisfactory.
Below a reproducible example:
library(excel.link)
library(openxlsx)
# Create some sample data
df1 <- data.frame(A = 1:5, B = letters[1:5])
df2 <- data.frame(X = 10:14, Y = LETTERS[10:14])
# Create a multi-sheet Excel file
wb <- createWorkbook()
addWorksheet(wb, "Sheet1")
addWorksheet(wb, "Sheet2")
writeData(wb, "Sheet1", df1)
writeData(wb, "Sheet2", df2)
# Save the file
file_name <- "test.xlsx"
saveWorkbook(wb, file_name,
overwrite = TRUE) # saved multi-sheet file without password protection
# Use excel.link to save a password protected file
excel.link::xl.save.file(r.obj = list(df1 = df1, df2 = df2),
filename = "protected.xlsx",
password = "password") # saved single-sheet protected file
Here is a solution (for Windows) using inspiration from the officerWinTools package.
This function writes, executes, and removes a temporary VBScript (.vbs) file that:
protect_workbook <- function(wb, pass) {
if(Sys.info()['sysname'] != "Windows"){
stop('The this function requires Windows operating system.')
}
wb_path <- file.path(getwd(), wb)
vbs_path <- file.path(getwd(), "tmp.vbs")
writeLines(
text = c(
'Set objExcel = CreateObject("Excel.Application")',
'objExcel.Visible = False',
'objExcel.DisplayAlerts = False',
sprintf('Set wb = objExcel.Workbooks.Open("%s")', normalizePath(wb_path)),
'wb.Saved = False',
sprintf('wb.Password = "%s"', pass),
'wb.Save',
'wb.Close (TRUE)',
'objExcel.Quit'
),
con = vbs_path
)
shell(shQuote(normalizePath(vbs_path)), "cscript", flag = "//nologo")
invisible(file.remove(vbs_path))
}
But this time use your new custom function protect_workbook()
instead of excel.link::xl.save.file()
.
library(openxlsx)
# Create some sample data
df1 <- data.frame(A = 1:5, B = letters[1:5])
df2 <- data.frame(X = 10:14, Y = LETTERS[10:14])
# Create a multi-sheet Excel file
wb <- createWorkbook()
addWorksheet(wb, "Sheet1")
writeData(wb, "Sheet1", df1)
addWorksheet(wb, "Sheet2")
writeData(wb, "Sheet2", df2)
# Save the file
file_name <- "test.xlsx"
saveWorkbook(wb, "test.xlsx")
# protect the workbook
protect_workbook(file_name, "opensesame")
Reprex files hosted with on GitHub