如何使用POI API访问Java中受密码保护的Excel工作簿

时间:2010-06-15 05:21:11

标签: java apache apache-poi

我想读取和写入受密码保护的Excel文件。如何使用Apache POI API执行此操作。

8 个答案:

答案 0 :(得分:14)

POI应该能够打开两个受保护的xls文件(使用 org.apache.poi.hssf.record.crypt )和受保护的xlsx文件(使用 org.apache.poi.poifs .crypt )。你试过这些吗?

如果您正在使用HSSF(对于xls文件),则需要在打开文件之前设置密码。您可以通过以下方式执行此操作:

 org.apache.poi.hssf.record.crypto.Biff8EncryptionKey.setCurrentUserPassword(password);

之后,HSSF应该能够打开你的文件。

对于XSSF,您需要以下内容:

POIFSFileSystem fs = new POIFSFileSystem(new FileInputStream("protect.xlsx"));
EncryptionInfo info = new EncryptionInfo(fs);
Decryptor d = new Decryptor(info);
d.verifyPassword(Decryptor.DEFAULT_PASSWORD);
XSSFWorkbook wb = new XSSFWorkbook(d.getDataStream(fs));

或者,在较新版本的Apache POI WorkbookFactory supports supplying the password when opening中,您可以执行以下操作:

Workbook wb = WorkbookFactory.create(new File("protected.xls"), "password"));

这适用于HSSF和XSSF,根据格式选择正确的密码,并以适当的格式传递给定密码。

答案 1 :(得分:2)

如果整个工作簿受密码保护(通过Excel菜单文件>另存为...>工具>常规选项... 然后提供密码),那么文件已加密,您无法通过POI读取和写入工作簿。

Excel Save As... General Options

答案 2 :(得分:2)

CODE:

FileInputStream fileInput = new FileInputStream("2.xls");         
BufferedInputStream bufferInput = new BufferedInputStream(fileInput);            
POIFSFileSystem poiFileSystem = new POIFSFileSystem(bufferInput);            
Biff8EncryptionKey.setCurrentUserPassword("test"); 
HSSFWorkbook workbook = new HSSFWorkbook(poiFileSystem, true); 

使用的罐子:

  • 公地编解码器-1.5.jar
  • 共享记录-1.1.jar
  • DOM4J-1.6.jar
  • jsr173_1.0_api.jar
  • 的junit-4.11.jar
  • 的log4j-1.2.13.jar
  • POI-3.10-FINAL-20140208.jar
  • POI-excelant-3.10-FINAL-20140208.jar
  • POI-OOXML-3.10-FINAL-20140208.jar
  • POI-OOXML-架构 - 3.10-FINAL-20140208.jar
  • resolver.jar
  • xbean.jar
  • xbean_xpath.jar
  • 的xmlbeans-qname.jar
  • xmlpublic.jar

答案 3 :(得分:2)

官方文档链接详细提供了xls,xlsx和其他支持格式的加密和解密可能性:http://poi.apache.org/encryption.html

即。如果是Binary Formats(xls):

// XOR/RC4 decryption for xls
Biff8EncryptionKey.setCurrentUserPassword("pass");
NPOIFSFileSystem fs = new NPOIFSFileSystem(new File("file.xls"), true);
HSSFWorkbook hwb = new HSSFWorkbook(fs.getRoot(), true);
Biff8EncryptionKey.setCurrentUserPassword(null);

对于基于XML的格式(xlsx):

EncryptionInfo info = new EncryptionInfo(filesystem);
Decryptor d = Decryptor.getInstance(info);

try {
    if (!d.verifyPassword(password)) {
        throw new RuntimeException("Unable to process: document is encrypted");
    }

    InputStream dataStream = d.getDataStream(filesystem);

    // parse dataStream

} catch (GeneralSecurityException ex) {
    throw new RuntimeException("Unable to process encrypted document", ex);
}

答案 4 :(得分:1)

Apache POI是excel处理的好方法。 但POI api仅提供读取受密码保护的Excel文件的选项。 没有使用pasword编写excel文件的选项。

Create a password protected excel file using apache poi?

检查此主题以了解有关受密码保护的Excel的更多信息。

答案 5 :(得分:0)

try 
{
    InputStream is = new FileInputStream("myfile.xlsx"); 
    POIFSFileSystem pfs = new POIFSFileSystem(is);

    EncryptionInfo info = new EncryptionInfo(pfs);
    Decryptor d = Decryptor.getInstance(info);

    if (!d.verifyPassword("passwordForFile")) 
    {
        System.out.println("Incorrect password!");
    }
    else 
    {
        System.out.println("Correct password!");

        //InputStream dataStream = d.getDataStream(pfs);

        // parse dataStream
    }
}
catch (Exception ex) 
{
    throw new RuntimeException("Unable to process encrypted document", ex);
}

答案 6 :(得分:0)

所提供的解决方案均不适用于xlsx文件,经过各种试验和错误,我发现此方法有效。

以下是我使用poi-4.0.1.jar和poi-ooxml-4.0.1.jar的工作解决方案

2018-01-05 : 9.8318

答案 7 :(得分:0)

请使用以下代码保存受Apache POI保护的excel文件密码。

FileOutputStream outputStream = null;
XSSFWorkbook workbook = new XSSFWorkbook();

try {
    outputStream = new FileOutputStream("Test.xlsx");

    XSSFSheet shtSummary = workbook.createSheet("Test");


    workbook.write(outputStream);
  } catch (Exception ex) {
        ex.printStackTrace();
  } finally {
        outputStream.close();
  }

  POIFSFileSystem fs = new POIFSFileSystem();
  EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);
  Encryptor enc = info.getEncryptor();
  enc.confirmPassword("mypassword");

  OPCPackage opc = OPCPackage.open(new File("Test.xlsx"), PackageAccess.READ_WRITE);
  OutputStream os = enc.getDataStream(fs);
  opc.save(os);
  opc.close();

  FileOutputStream fos = new FileOutputStream("Test.xlsx");
  fs.writeFilesystem(fos);
  fos.close();

此代码效果很好。此解决方案适用于.xslx格式。

以下代码适用于.xls格式。

String fname = "Test.xls";

FileInputStream fileInput = null;
BufferedInputStream bufferInput = null;
POIFSFileSystem poiFileSystem = null;
FileOutputStream fileOut = null;

try {
    fileInput = new FileInputStream(fname);
    bufferInput = new BufferedInputStream(fileInput);
    poiFileSystem = new POIFSFileSystem(bufferInput);

    Biff8EncryptionKey.setCurrentUserPassword("mypassword");
    HSSFWorkbook workbook = new HSSFWorkbook(poiFileSystem, true);
    HSSFSheet sheet = workbook.getSheetAt(0);

    HSSFRow row = sheet.createRow(0);
    Cell cell = row.createCell(0);

    cell.setCellValue("THIS WORKS!");

    fileOut = new FileOutputStream(fname);
    workbook.writeProtectWorkbook(Biff8EncryptionKey.getCurrentUserPassword(), "");
    workbook.write(fileOut);
}
catch (Exception ex) {

    System.out.println(ex.getMessage());
}
finally {
    try {

        bufferInput.close();
    }
    catch (IOException ex) {

        System.out.println(ex.getMessage());
    }

    try {

        fileOut.close();
    }
    catch (IOException ex) {

        System.out.println(ex.getMessage());
    }
}

这两种解决方案都对我有用。我发现这是一个很好的解决方案。