Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 使用Apache POI更新和加密现有xlsx文件_Excel_Apache Poi - Fatal编程技术网

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

Excel 使用Apache POI更新和加密现有xlsx文件,excel,apache-poi,Excel,Apache Poi,我有现有的xlsx电子表格。我正在使用ApachePOI3.17阅读它,添加一些条目,并将其另存为新文件中受密码保护的电子表格。 运行程序后,新文件受密码保护,但我看不到新条目,只看到以前存在的条目。这里是程序的简化版本,它打开空的电子表格,写入新的单元格,并用密码保存在新文件中。当我使用密码在Excel 2010中打开文件时,仍然会看到空的电子表格。 任何帮助都将不胜感激。谢谢 public static void main(String[] args) { try { POIF

我有现有的xlsx电子表格。我正在使用ApachePOI3.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
在提交更改时存在差异。
xssf工作簿
中的更改将仅在
XSSFWorkbook.write
时提交到
OPCPackage
。因此,如果您没有(或无法)写出
XSSFWorkbook
,则
OPCPackage
将保持不变

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

因此,在我看来,它不可能以编程方式影响
XSSFWorkbook
和它的
OPCPackage
之间的提交过程

但是代码的主要问题是,您正在将未更新的
OPCPackage
写入
加密机的数据流。相反,您应该编写已更新的
工作簿

例如:

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();

 }
}

答案在@kiwiwings中:当关闭
encos
:线程“main”org.apache.poi.EncryptedDocumentException:java.io.FileNotFoundException:/tmp/poifiles/encrypted_Package1071788535456764crypt(…)时,您的代码使用
ApachePOI
版本
失败在org.apache.poi.poifs.crypt.standard.StandardEncryptor$StandardCipherOutputStream.ProcessPoifsWriteEvent(StandardEncryptor.java:201)。。。在org.apache.poi.poifs.crypt.standard.StandardEncryptor$StandardCipherOutputStream.close(StandardEncryptor.java:169)
@AxelRichter:你说得对,我刚刚在主干上测试了代码,并且因为以下原因更改了关闭habbit。我需要在发行说明中更清楚地说明。@kiwiwings:好的。由于您正在
工作簿wb=WorkbookFactory.create(新文件(“empty.xlsx”))中使用
文件
,则
empty.xlsx
也会更新,而
wb.write
会更新
OPCPackage
。因此在此之后,
empty.xlsx
也包含
B2
中的新值,并且不再是“空的”;-)。正如我在回答中所说,它不可能以编程方式影响
XSSFWorkbook
和它的
OPCPackage
之间的提交过程。我已经通过。。。我将通过