Currently using Apache POI 3.16 on Java version 1.7.0-251 (Unix)
Taking a leaf out of the example explained by @Aniruddh Chandegra (How to create and edit a password protect excel sheet using Apache POI 3.14?)
[EDIT - Added the below code to show what I'm doing: creates XSSFWorkbook and extracts data, then encrypts]
Note: I'm running the code on - server-side Javascript - using Mozilla Rhino v1.7R3 which provides support for nearly all of ECMAScript Edition 5 plus a few features from Mozilla Javascript 1.8.
var wb = new XSSFWorkbook();
var createHelper = wb.getCreationHelper();
// Begin filling in rows/cells
addMostRecentSheet(wb);
var filepath = [hidden]
var fileOut = new java.io.FileOutputStream(filepath);
wb.write(fileOut);
fileOut.close();
var fs = new POIFSFileSystem();
var info = new EncryptionInfo(EncryptionMode.agile, CipherAlgorithm.aes192, HashAlgorithm.sha384, -1, -1, null);
var enc = info.getEncryptor();
enc.confirmPassword("password");
var os = enc.getDataStream(fs);
opc.saveImpl(os); //<<-----Crash there - unable to save /x1/styles.xml
opc.close();
var fos = new java.io.FileOutputStream(filepath);
fs.writeFilesystem(fos);
fos.close();
I eventually managed to save password protected xlsx but I had to remove the styling of Date columns.
Below is the code to format cells into Date celltype:
function createDateCell(row, colNum, value)
{
var cell;
if (value)
{
cell = row.createCell(colNum);
cell.setCellValue(value);
var cellStyle = wb.createCellStyle();
cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd/mm/yyyy"));
cell.setCellStyle(cellStyle)
}
else
{
cell = row.createCell(colNum, Cell.CELL_TYPE_BLANK);
}
return cell;
}
Yet when running the program, I keep getting this error, is there a workaround to keep the Date column type? The error message:
org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException:
Fail to save: an error occurs while saving the package :
The part /xl/styles.xml failed to be saved in the stream with marshaller
org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller@216fb8e
createDateCell
creates a newCellStyle
for each cell. This is wrong.CellStyle
s are on workbook level and are stored in/xl/styles.xml
. If yourcreateDateCell
creates thousand date cells, then it also creates thousand times the sameCellStyle
. Thus the/xl/styles.xml
contains thousand times the sameXML
for thatCellStyle
. Don't do that. – Axel Richtervar cellStyle = wb.createCellStyle(); cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd/mm/yyyy"));
only once on workbook level. Then hand over that oneCellStyle
to the cells creator function, likefunction createDateCell(row, colNum, value, cellStyle)
. – Axel Richter