当前位置: 首页 > 知识库问答 >
问题:

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

缑永年
2023-03-14

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

共有1个答案

花欣然
2023-03-14

这里的问题是XSSFWorkbook和它的OPCPackage在提交更改时存在差异。只有在xssf工作簿时,xssf工作簿中的更改才会提交到OPCPackage。写。因此,如果您没有(或无法)写出XSSFWorkbook,则OPCPackage将保持不变。

另一方面,如果您写出XSSFWorkbook,它总是将更改提交到创建工作簿的OPCPackage。因此,如果这是从文件创建的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); 
  wb.close();

  OutputStream os = new FileOutputStream(new File("./f.xlsx"));
  fs.writeFilesystem(os);
  os.close();

 }
}

 类似资料:
  • 我正在写一个程序,它需要从excel文件中读取和写入数据,而不考虑格式(xls或xlsx)。 我知道ApachePOI,但它似乎有不同的类来处理xls文件(HSSF)和xlsx(XSSF)文件。 任何人都知道我将如何实现我在这里的目标。(也欢迎使用POI以外的API的想法)。

  • 我正在一个smal家庭项目中工作,我需要加密用户输入的文本。文本文件是在程序def personal_save()的第一部分创建的:但是我想要实现的是,当用户按下主页上的关闭按钮时,def file_Encryption读取生成的txt文件并对其进行加密。我已经找到了一个代码与简单的加密,并试图改变代码,但没有运气,因为我是新的编程世界。 我已经创建了一个函数,当用户按下退出按钮时,文件应该用静态

  • 在mac osx环境中使用Apache POI 3.8读取文件时,由于无法加载xlsx文件,因此在Windows中使用Open XML SDK 2.0 for Microsoft Office创建了一个文件。下面是堆栈跟踪。我可以打开文件并查看它。 同样的代码适用于我在mac os环境中创建的文件。如果我在处理之前打开并保存文件,我不会有任何问题。注意:保存后文件大小增加。是在.NET中生成文件并

  • 我刚接触熊猫,似乎无法使用合并功能: 对于列a上的左连接,我想通过连接键更新公共列。注:c列中的最后一个值来自左表,因为不存在匹配项。 我应该如何使用Pandas merge函数来实现这一点?非常感谢。

  • 问题内容: 我已经在过去4-5个小时内进行了研究,尽管找到了从几种方法到整个〜100行类的所有内容的“答案”,但似乎找不到真正 有效 的答案。我无法想象没有一些简单的功能可以完成如此​​琐碎的事情:P 我有一组预先存在的公用/专用密钥(实际上,有两组-一组由ssh-keygen生成,另一组由openssl生成,所以..什么格式都可以用)。 我所追求的只是一个简单的java等效于我在python中编

  • 在过去的4-5个小时里,我一直在研究这个问题,尽管找到了从几个方法到整个100行课程的“答案”,但似乎找不到一个真正有效的答案。我无法想象,没有什么简单的函数可以做这样一件小事:P 我有一组预先存在的公钥/私钥(实际上,两组-一组由ssh-keygen生成,另一组由openssl生成,所以... 我所追求的只是一个简单的java,相当于我用python编写的东西- 任何帮助都会很棒!