Python or LibreOffice Save xlsx file encrypted with password
<p>I am trying to save an Excel file <em>encrypted</em> with password. I have tried following the guide on <a href="https://help.libreoffice.org/Common/Protecting_Content_in" rel="nofollow">https://help.libreoffice.org/Common/Protecting_Content_in</a> - and works perfectly. However, this is in the GUI, but I am looking for a solution using the command line interface in headless mode.</p>

<p>I have looked at the <code>man libreoffice</code>, but I could not find anything in there. </p>

<p>Likewise I have looked at the documentation of the Python 3 library <code>openpyxl</code>, but I did not find anything useful there either.</p>

<p>Is it possible to save an Excel 2007+ file <em>encrypted</em> with a password on Ubuntu 14.04/16.04 using the command line (or Python library) that do not require any user interaction or X session?</p>

<p>There is solution using <a href="http://jython.org" rel="nofollow">Jython</a> and <a href="https://poi.apache.org/" rel="nofollow">Apache POI</a>. If you want like to use it from CPython/PyPy, you can use <a href="https://docs.python.org/3/library/subprocess.html" rel="nofollow">subprocess</a> module to call external Jython script.</p>

<ol>
<li>I assume that you have Java JRE/JDK installed</li>
<li>Create <em>non-encrypted</em> xlsx file with Excel/Calc or use <a href="http://xlsxwriter.readthedocs.io/" rel="nofollow">xlsxwriter</a> or <a href="https://openpyxl.readthedocs.io/en/default/" rel="nofollow">openpyxl</a> and save it as <em>test1.xlsx</em></li>
<li>Download standalone Jython</li>
<li>Download Apache POI</li>
<li>Extract Apache POI in same dir where is standalone Jython jar</li>
<li>Save following Jython script as <em>encrypt.py</em>:</li>
</ol>

<pre class="lang-py prettyprint-override"><code>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)
</code></pre>

<ol start="7">
<li>Call it from console:</li>
</ol>

<pre class="lang-bash prettyprint-override"><code>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
</code></pre>

<p>Where:</p>

<ul>
<li>encrypt.py - name of script</li>
<li>test1.xlsx - input filename</li>
<li>test1enc.xlsx - output filename</li>
<li>12345678 - password</li>
</ul>

<p>Final <em>encrypted</em> xslx should be in <em>test1enc.xlsx</em>.</p>

python excel encryption ubuntu-14.04 libreoffice-calc