我有现有的xlsx电子表格。我正在使用Apache POI 3.17来阅读它,添加一些条目并将受密码保护的电子表格保存在新文件中。 运行程序后,新文件受密码保护,但我看不到新条目,只有以前存在的条目。这是该程序的简化版本,它打开空电子表格,写入新单元格并使用密码保存在新文件中。当我使用密码在Excel 2010中打开文件时,我仍然看到空的电子表格。 任何帮助将不胜感激。谢谢
public static void main(String[] args) {
try {
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.standard);
Encryptor enc = info.getEncryptor();
enc.confirmPassword("passw");
File is = new File("./empty.xlsx");
OPCPackage opc = OPCPackage.open(is, PackageAccess.READ_WRITE);
Workbook wb = WorkbookFactory.create(opc);
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.createRow(1);
Cell cell = row.createCell(1);
cell.setCellType(Cell.CELL_TYPE_STRING);
cell.setCellValue("CRYPT");
OutputStream encos = enc.getDataStream(fs);
opc.save(encos);
opc.close();
OutputStream fos = new FileOutputStream(new File("./f.xlsx"));
fs.writeFilesystem(fos);
fos.close();
}
catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
这里的问题是在XSSFWorkbook
和它之间的OPCPackage
之间提交更改的差异。XSSFWorkbook
中的更改将仅在XSSFWorkbook.write
时提交到OPCPackage
。因此,如果您不(或不能(写出XSSFWorkbook
,则OPCPackage
保持不变。
另一方面,如果写出XSSFWorkbook
,它始终会向创建工作簿的OPCPackage
提交更改。因此,如果这是从File
创建的OPCPackage
,则始终会在工作簿可能写入另一个文件之前更新此文件。这也很烦人。
所以在我看来,它缺乏以编程方式影响XSSFWorkbook
和它之间的提交过程的可能性OPCPackage
.
但是你的代码的主要问题是你正在将没有更新的OPCPackage
写入Encryptor
的数据流。相反,您应该编写已更新的Workbook
。
所以例如:
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.poifs.crypt.*;
import org.apache.poi.ss.usermodel.*;
import java.io.*;
class ExcelUpdateAndEncrypt {
public static void main(String[] args) throws Exception {
POIFSFileSystem fs = new POIFSFileSystem();
EncryptionInfo info = new EncryptionInfo(EncryptionMode.standard);
Encryptor enc = info.getEncryptor();
enc.confirmPassword("passw");
FileInputStream is = new FileInputStream("./empty.xlsx");
Workbook wb = WorkbookFactory.create(is);
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.createRow(1);
Cell cell = row.createCell(1);
cell.setCellValue("CRYPT");
OutputStream encos = enc.getDataStream(fs);
wb.write(encos);
encos.close();
wb.close();
OutputStream os = new FileOutputStream(new File("./f.xlsx"));
fs.writeFilesystem(os);
os.close();
}
}