There is solution using Jython and Apache POI. If you want like to use it from CPython/PyPy, you can use subprocess module to call external Jython script.
- I assume that you have Java JRE/JDK installed
- Create non-encrypted xlsx file with Excel/Calc or use xlsxwriter or openpyxl and save it as test1.xlsx
- Download standalone Jython
- Download Apache POI
- Extract Apache POI in same dir where is standalone Jython jar
- Save following Jython script as encrypt.py:
import os
import sys
from java.io import BufferedInputStream
from java.io import FileInputStream
from java.io import FileOutputStream
from java.io import File
from java.io import IOException
from org.apache.poi.poifs.crypt import EncryptionInfo, EncryptionMode
from org.apache.poi.poifs.crypt import CipherAlgorithm, HashAlgorithm
from org.apache.poi.poifs.crypt.agile import AgileEncryptionInfoBuilder
from org.apache.poi.openxml4j.opc import OPCPackage, PackageAccess
from org.apache.poi.poifs.filesystem import POIFSFileSystem
from org.apache.poi.ss.usermodel import WorkbookFactory
def encrypt_xlsx(in_fname, out_fname, password):
# read
in_f = File(in_fname)
in_wb = WorkbookFactory.create(in_f, password)
in_fis = FileInputStream(in_fname)
in_wb.close()
# encryption
out_poi_fs = POIFSFileSystem()
info = EncryptionInfo(EncryptionMode.agile)
enc = info.getEncryptor()
enc.confirmPassword(password)
opc = OPCPackage.open(in_f, PackageAccess.READ_WRITE)
out_os = enc.getDataStream(out_poi_fs)
opc.save(out_os)
opc.close()
# write
out_fos = FileOutputStream(out_fname)
out_poi_fs.writeFilesystem(out_fos)
out_fos.close()
if __name__ == '__main__':
in_fname = sys.argv[1]
out_fname = sys.argv[2]
password = sys.argv[3]
encrypt_xlsx(in_fname, out_fname, password)
- Call it from console:
java -cp "jython-standalone-2.7.0.jar:poi-3.15/lib/commons-codec-1.10.jar:poi-3.15/lib/commons-collections4-4.1.jar:poi-3.15/poi-3.15.jar:poi-3.15/poi-ooxml-3.15.jar:poi-3.15/poi-ooxml-schemas-3.15.jar:poi-3.15/ooxml-lib/curvesapi-1.04.jar:poi-3.15/ooxml-lib/xmlbeans-2.6.0.jar" org.python.util.jython -B encrypt.py test1.xlsx test1enc.xlsx 12345678
Where:
- encrypt.py - name of script
- test1.xlsx - input filename
- test1enc.xlsx - output filename
- 12345678 - password
Final encrypted xslx should be in test1enc.xlsx.