Как я могу получить доступ к защищенной паролем книге Excel на Java с помощью POI api

Я хочу читать и записывать файлы, защищенные паролем Excel. Как это сделать, используя API Apache POI.

Ответ 1

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 поддерживает ввод пароля при открытии, поэтому вы можете просто сделать что-то вроде:

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

Это будет работать как для HSSF, так и для XSSF, выбирая правильный в зависимости от формата и передавая заданный пароль соответствующим образом для формата.

Ответ 2

Если вся книга защищена паролем (перейдя в меню Excel Файл > Сохранить как... > Инструменты > Общие параметры..., затем укажите пароль), то файл будет зашифрован и вы не можете читать и писать в книгу через POI.

Excel Save As... General Options

Ответ 3

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
  • пои-3,10-FINAL-20140208.jar
  • пои-excelant-3,10-FINAL-20140208.jar
  • пои-OOXML-3,10-FINAL-20140208.jar
  • пои-OOXML-схема-3,10-ЗАВЕРШЕНИЕ-20140208.jar
  • resolver.jar
  • xbean.jar
  • xbean_xpath.jar
  • XMLBeans-qname.jar
  • xmlpublic.jar

Ответ 4

В официальной ссылке документации подробно описаны возможности шифрования и дешифрования f для 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);
}

Ответ 5

Apache POI является хорошим api для обработки excel. Но POI api предоставляет только возможность читать защищенные паролем файлы excel. Нет опции для записи файла excel с помощью пароля.

Создайте защищенный паролем файл excel с помощью apache poi?

Отметьте эту тему, чтобы узнать больше о защищенном паролем excel.

Ответ 6

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

Ответ 7

Ни одно из предложенных решений не помогло мне для файла xlsx. После различных проб и ошибок я обнаружил, что это работает.

Ниже мое рабочее решение с poi-4.0.1.jar & пои-OOXML-4.0.1.jar

private OutputStream getEncryptingOutputStream(POIFSFileSystem fileSystem, String password) throws IOException, GeneralSecurityException
{
    EncryptionInfo encryptionInfo = new EncryptionInfo(EncryptionMode.standard);
    Encryptor encryptor = encryptionInfo.getEncryptor();
    encryptor.confirmPassword(password);
    return encryptor.getDataStream(fileSystem);
}

private void encryptSpreadSheet(String sourcePath, String destinationPath) throws IOException, GeneralSecurityException, InvalidFormatException
{
    try (POIFSFileSystem fileSystem = new POIFSFileSystem())
    {
      //sourcePath = "/var/tmp/dummy.xlsx"
      //destinationPath = "/var/tmp/dummy_encrypted.xlsx"
      try (Workbook wb = WorkbookFactory.create(new File(sourcePath));
            OutputStream out = getEncryptingOutputStream(fileSystem, "password");)
      {
         wb.write(out);
      }

      try (FileOutputStream fileOutputStream = new FileOutputStream(new File(destinationPath)))
      {
          fileSystem.writeFilesystem(fileOutputStream);
      }
    }
}