我有现有的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();
}
}
答案 0 :(得分:1)
此处的问题是XSSFWorkbook
和OPCPackage
之间提交更改的差异。只有XSSFWorkbook
时,OPCPackage
中的更改才会提交给XSSFWorkbook.write
。因此,如果您没有(或不能)写出XSSFWorkbook
,OPCPackage
保持不变。
另一方面,如果您写出XSSFWorkbook
,则始终会将更改提交到创建工作簿的OPCPackage
。因此,如果这是从OPCPackage
创建的File
,则在将工作簿写入另一个文件之前,始终会更新此文件。这也很烦人。
所以在我看来,它缺乏程序性地影响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);
wb.close();
OutputStream os = new FileOutputStream(new File("./f.xlsx"));
fs.writeFilesystem(os);
os.close();
}
}