使用Apache POI更新和加密现有xlsx文件

时间:2018-06-12 20:31:43

标签: excel apache-poi

我有现有的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();
  }
}

1 个答案:

答案 0 :(得分:1)

此处的问题是XSSFWorkbookOPCPackage之间提交更改的差异。只有XSSFWorkbook时,OPCPackage中的更改才会提交给XSSFWorkbook.write。因此,如果您没有(或不能)写出XSSFWorkbookOPCPackage保持不变。

另一方面,如果您写出XSSFWorkbook,则始终会将更改提交到创建工作簿的OPCPackage。因此,如果这是从OPCPackage创建的File,则在将工作簿写入另一个文件之前,始终会更新此文件。这也很烦人。

所以在我看来,它缺乏程序性地影响XSSFWorkbookOPCPackage之间提交过程的可能性。

但是您的代码的主要问题是您正在将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();

 }
}