Reputation: 81
I am trying to password protect an entire Excel file (same functionality as File > Protect Workbook > Encrypt with Password) using Python.
I have come across openpyxl and the protection features it offers (https://openpyxl.readthedocs.io/en/stable/protection.html) seems to fulfill this need. I have the following code:
from openpyxl import Workbook
from openpyxl import load_workbook
test_spreadsheet = "test.xlsx"
wb = load_workbook(test_spreadsheet)
wb.security.workbookPassword = "password"
However, I am getting the following error:
AttributeError: 'NoneType' object has no attribute 'workbookPassword'
Does anyone have an idea of what is causing this AttributeError? I have printed the sheetnames from wb and that is correctly printing the tabs in my Excel document.
Upvotes: 8
Views: 5387
Reputation: 9872
For a default-constructed workbook, the security
property is initialized by default:
self.security = DocumentSecurity()
Reference: 1
However, workbooks constructed by reading a workbook are not just default-constructed; they are also manipulated by a Parser
object:
wb_part = _find_workbook_part(self.package)
self.parser = WorkbookParser(self.archive, wb_part.PartName[1:], keep_links=self.keep_links)
self.parser.parse()
wb = self.parser.wb
...
self.wb = wb
Reference: 2
Parser.init
does default-construct a Workbook
, but then overrides specific properties with those of the source document:
self.wb.security = package.workbookProtection
Reference: 3
This means that for files that had no security settings, the imported workbook object has a value of None
for its security
property (and thus your error, as None
clearly has no attribute workbookPassword
).
Your solution is then to create a default WorkbookProtection()
, assign it to the workbook, and then set the workbook password.
Upvotes: 0
Reputation: 6639
As the Openpyxl document states "Workbook Protection To prevent other users from viewing hidden worksheets, adding, moving, deleting, or hiding worksheets, and renaming worksheets, you can protect the structure of your workbook with a password." It's not the same as File > Protect Workbook > Encrypt with Password. Also does not work with an existing workbook.
If you run the following code, and open the newly created book 'test.xlsx' you should see it will open without a password however you cannot do any of those actions in italics above unless you go to the 'changes' toolbar and click 'Protect Workbook' then enter the password.
from openpyxl import Workbook
from openpyxl import load_workbook
test_spreadsheet = "test.xlsx"
wb = Workbook()
wb.security.workbookPassword = 'password'
wb.security.lockStructure = True
wb.save(test_spreadsheet)
I don't believe openpyxl supports the option you want.
Upvotes: 0