1

How to check if excel file is protected with password the fastest way (without trying to open it and placing an exception)?

Updated:

from zipfile import *
from openpyxl import load_workbook
filename = 'Z:\\path_to_file\\qwerty.xlsm' # protected one
try:
    wb = load_workbook(filename, data_only=True, read_only=True) 
except (BadZipfile) as error:
    print(is_zipfile(filename))

A problem is that I got False as an output, thus I cannot get rid of the exception and replace it with is_zipfile() condition.

martineau
  • 119,623
  • 25
  • 170
  • 301
cat_on_the_mat
  • 100
  • 1
  • 9

3 Answers3

0

Solution using the openpyxl library:

import openpyxl
wb = openpyxl.load_workbook(PATH_TO_FILE)

if wb.security.lockStructure == None:
    #  no password, act accordingly
    ...
else:
    #  password, act accordingly
    ...
Python Newb
  • 89
  • 1
  • 4
  • i got an error: zipfile.BadZipFile: "File is not a zip file", the line i try to load_workbook (thought it was not a zip file at all, if i access the file normally the password is required), if i'm loading a protected file. Also even load_workbook(PATH_TO_FILE, data_only = True, read_only= True) takes significant time to open a heavy file, while my goal is to filter many files – cat_on_the_mat Feb 06 '19 at 17:18
0

You can do this using the protection._password property of a sheet:

wb = openpyxl.load_workbook("C:\\Users\\...\\Downloads\\some_workbook.xlsx")

print(wb.worksheets[0].protection._password)

You can do this for whatever sheet you would like, based off the worksheets in the workbook.

If there is no password, the value is None. Otherwise, it returns the hashed password.

So, you can create a method to check this:

def password_protected(sheet):
   if sheet.protection._password is None:
      return False
   return True

The same method applies for the whole workbook, the property is just workbook.protection._workbook_password.

Nick
  • 823
  • 2
  • 10
  • 22
  • if i try to upload protected file, I got permission denied and an error zipfile.BadZipFile: "File is not a zip file" (while it was not a zip file, but probably encrypted) , so this is a reason why i need to know weather the file is protected or not – cat_on_the_mat Feb 06 '19 at 17:45
  • Can you post some example code? And upload to where? – Nick Feb 06 '19 at 17:49
  • import openpyxl import load_workbook filename = 'qwerty.xlsm' wb = load_workbook(filename, data_only = True, read_only = True) # fails here ! if depreciate data_only, read_only nothing changes – cat_on_the_mat Feb 06 '19 at 18:06
  • are you providing the full path? – Nick Feb 06 '19 at 18:09
  • yes, and it works fine with all not-protected files from the same folder perfectly. I tried to open protected file as if it were a zip archive, but i got an error "not a zip file ". Actually I don't have a goal to open any passworded files at all, i need to filter 100500 files and keep not protected only. – cat_on_the_mat Feb 06 '19 at 18:30
  • https://stackoverflow.com/questions/29720587/python-reading-password-protected-word-documents-with-zipfile take a look at this – Nick Feb 06 '19 at 18:42
  • It seems that the easiest thing to do is catch the exception and move on. Especially if you don't care about files that are password protected. – Nick Feb 06 '19 at 18:49
0

When trying to open a password protected workbook with openpyxl, this indeed gives a error zipfile.BadZipFile so a workaround would be to use:

import zipfile
zipfile.is_zipfile("workbook.xlsx")
Juta
  • 411
  • 1
  • 5
  • 12
  • Almost. A problem is that I got False (code example is in the main question now) – cat_on_the_mat Feb 07 '19 at 17:04
  • Are all excel files workbook password protected? Because I guess it might evaluate to False when it is the worksheet that is password protected – Juta Feb 08 '19 at 10:21
  • No, some files are protected, and some aren't. The fact is that here result is false for all of them. So, this is_zipfile is useless here. – cat_on_the_mat Feb 18 '19 at 17:54