javascript - styles.xml 破坏受密码保护的 XSSFWorkbook (Apache POI v3.16) 保存过程
问题描述
目前在 Java 版本 1.7.0-251 (Unix) 上使用 Apache POI 3.16
从@Aniruddh Chandegra 解释的示例中取出一片叶子(如何使用 Apache POI 3.14 创建和编辑密码保护 excel 表?)
[编辑-添加以下代码以显示我在做什么:创建 XSSFWorkbook 并提取数据,然后加密]
注意:我正在使用 Mozilla Rhino v1.7R3 在服务器端 Javascript 上运行代码,它提供了对几乎所有 ECMAScript Edition 5 以及 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();
我最终设法保存了受密码保护的 xlsx,但我不得不删除日期列的样式。
以下是将单元格格式化为日期单元格类型的代码:
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;
}
但是在运行程序时,我不断收到此错误,是否有解决方法来保留日期列类型?错误信息:
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
解决方案
要创建日期样式单元格,您需要执行以下操作:
var wb = new XSSFWorkbook();
var createHelper = wb.getCreationHelper();
var dateStyle = wb.createCellStyle();
dateStyle.setDataFormat(createHelper.createDataFormat().getFormat("dd/mm/yyyy"));
你只需要做一次。通过将 cellStyle 设置在顶部,您只填充了一次 /xl/styles.xml。
填充单元格时,您只需将 dateStyle 添加到函数中:
createDateCell(row, colNum++, tables.SHE_SOUTH.DOB.value, dateStyle);
函数createDateCell只需添加 cellStyle:
function createDateCell(row,colNum,value, cellStyle){
var cell;
if(value){
cell = row.createCell(colNum, Cell.CELL_TYPE_NUMERIC);
cell.setCellValue(value);
cell.setCellStyle(cellStyle);
}
else
{
cell = row.createCell(colNum, Cell.CELL_TYPE_BLANK);
}
return cell;
}
这样 /xl/styles.xml 就不会像以前那样臃肿了。这允许对工作簿进行加密。工作一种享受,归功于Axel Richter
推荐阅读
- python-3.x - 命令返回非零退出状态 9
- javascript - 在特定索引处插入新跨度
- haskell - 使用 foldr 制作过滤器
- php - 从android解析json字符串并使用php插入数据库
- sql-server - 如何在 SQL Server/Oracle/Postgres 中将 json 字符串转换为 varbinary?
- c# - Word 互操作:如何确定 Word 文档选择是否包含段落标记?
- c# - ASP.NET MVC - 如何运行单独的进程并让用户继续正常的应用程序使用?
- php - 在哪里编写将在 Wordpress 博客的内容和小部件中使用的数组
- flask - 期待 http://127.0.0.1:5000/;但只有“进程以退出代码 0 完成”
- java - 如何调用和解析 postgres 用户定义类型