Hi Erick,
I think there's a (embarrassing) problem with the encryption of .xlsx files.
Currently only .docx seem to work.
When I get the encryption stuff working (again), I try to answer your original
question.
The short version of it is:
- The encryption implementation currently writes anyway to temp files,
as it needs to calculate the size of the encrypted stream and both, the
stream size
and the stream itself, are subject to the hmac-calculation, i.e. it would be
only possible
to do a streaming encryption, when you know the stream size beforehand, but
this
handling is not implemented
- I wouldn't call ((XSSFWorkbook) workbook).getPackage() ... .save() directly
have a look at XSSFWorkbook.write(), there's also a call to onSave(...)
- OPCPackage.open(InputStream) reads all the references and parts of the ooxml
file
in-memory (see javadoc for it). Although you want to avoid it, writing the
content
to a temp file and using OPCPackage.open(File) might be slightly better.
If you want to read an encrypted file, you might also want to use the
NPOIFSFileSystem(File)
Best wishes,
Andi
On 08.04.2014 14:44, Erick Lichtas wrote:
Hi Everyone,
I am trying to integrate excel password protection of XSSF documents into an
existing process that currently uses POI to write the documents. I am looking
to avoid the need to write the file to disk before encrypting it and would like
it to be streamed through the encryption as it is being written out.
I have been able to accomplish this by using Piped streams and a separate
reader thread:
PipedInputStream pis = new PipedInputStream(16 * 1024);
PipedOutputStream pos = new PipedOutputStream(pis);
WorkbookWriterThread thread = new WorkbookWriterThread(pis,
outputFile, cipherAlg,
hashAlg, password);
thread.start();
workbook.write(pos);
...but this is not ideal and would like to avoid using a separate thread if
possible.
Looking through the code, it appears the OPCPackage IS available on the
XSSFWorkbook object, but does not appear to be loaded/committed completely by
the time I try to write it to the encryption stream.
outputEncryptionStream = enc.getDataStream(fs);
destOutputStream = new FileOutputStream(outputFile);
pkg = ((XSSFWorkbook) workbook).getPackage();
pkg.save(outputEncryptionStream);
fs.writeFilesystem(destOutputStream);
However if I open() the OPCPackage with an input stream or file, it works as
expected.
opcPackage = OPCPackage.open(in);
outputEncryptionStream = enc.getDataStream(fs);
opcPackage.save(outputEncryptionStream);
fs.writeFilesystem(out);
My ultimate goal is to avoid having duplicate workbook data in memory,
considering the existing memory footprint of an XSSFWorkbook. What I am seeing
right now is that the OPCPackage.open(InputStream) gives a brief spike in
memory which seems to be GC'd almost immediately before the data starts being
written to disk, but I'm worried this spike could be the tipping point in an
OOM.
It seems like an achievable goal to be able to stream the existing workbook
through an encryptor when writing it out to disk, and I'm wondering what I
might be missing. Does anyone have any suggestions on how to accomplish this?
ERICK LICHTAS
Linoma Software
Senior Software Engineer
p. 402.944.4242 x714
f. 402.944.4243
www.LinomaSoftware.com<www.linomasoftware.com>
www.GoAnywheremft.com<www.goanywheremft.com>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]