Last active
May 30, 2022 09:53
-
-
Save terrdavis/b219e92d42dc5f9ca526aa0047d1a1d1 to your computer and use it in GitHub Desktop.
Open an xls file using xlrd even if it has protected sheets.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# based on: https://stackoverflow.com/a/52290873/9560908 | |
import contextlib | |
import tempfile | |
import msoffcrypto | |
import xlrd | |
@contextlib.contextmanager | |
def handle_protected_workbook(wb_filepath): | |
try: | |
with xlrd.open_workbook(wb_filepath) as wb: | |
yield wb | |
except xlrd.biffh.XLRDError as e: | |
if str(e) != "Workbook is encrypted": | |
raise | |
# Try and unencrypt workbook with magic password | |
wb_path = Path(wb_filepath) | |
with wb_path.open("rb") as fp: | |
wb_msoffcrypto_file = msoffcrypto.OfficeFile(fp) | |
try: | |
# Yes, this is actually a thing | |
# https://nakedsecurity.sophos.com/2013/04/11/password-excel-velvet-sweatshop/ | |
wb_msoffcrypto_file.load_key(password="VelvetSweatshop") | |
except Exception as e: | |
raise Exception('Unable to read file "{}"'.format(wb_path)) from e | |
# Magic Excel password worked | |
with tempfile.NamedTemporaryFile(delete=False) as tmp_wb_unencrypted_file: | |
# Decrypt into the tempfile | |
wb_msoffcrypto_file.decrypt(tmp_wb_unencrypted_file) | |
decrypted_path = Path(tmp_wb_unencrypted_file.name) | |
try: | |
with xlrd.open_workbook(str(decrypted_path)) as wb: | |
yield wb | |
finally: | |
decrypted_path.unlink() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment