Apache POI зашифрованный xlsx не может быть открыт в Excel - PullRequest
0 голосов
/ 20 сентября 2018

Я пытаюсь создать зашифрованный файл xlsx, используя Apache POI.Вот мой код, который работает просто отлично:

public static void Encrypt(String data) throws IOException, GeneralSecurityException, InvalidFormatException {

    Workbook wb = new XSSFWorkbook();
    Sheet sheet1 = wb.createSheet("sheet1");
    sheet1.createRow(0).createCell(0).setCellValue(data);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    wb.write(bos);
    bos.close();

    POIFSFileSystem fs = new POIFSFileSystem();
    EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile, CipherAlgorithm.aes256, HashAlgorithm.sha512, 256, 16, ChainingMode.cbc);
    Encryptor enc = info.getEncryptor();
    enc.confirmPassword("pass");

    OPCPackage opc = OPCPackage.open(new ByteArrayInputStream(bos.toByteArray()));
    OutputStream os = enc.getDataStream(fs);
    opc.save(os);
    opc.close();

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

Проблема в том, что когда я открываю сгенерированный файл, Excel продолжает жаловаться, что файл поврежден.Я также пытался изменить экземпляр EncryptionInfo с разными режимами шифрования, но ничего не изменилось.

Может кто-нибудь дать мне подсказку?!?

1 Ответ

0 голосов
/ 20 сентября 2018

Зашифрованный поток вывода должен быть закрыт перед записью файловой системы.В вашем случае ему не хватает os.close(); после opc.save(os);.

Но почему для обхода вообще используется ByteArrayOutputStream?

У меня работает следующее:

import java.io.*;
import org.apache.poi.poifs.filesystem.*;
import org.apache.poi.poifs.crypt.*;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class XSSFEncryption {

 public static void doEncrypt(String data) throws Exception {

  POIFSFileSystem fs = new POIFSFileSystem();
  EncryptionInfo info = new EncryptionInfo(EncryptionMode.agile);

  Encryptor enc = info.getEncryptor();
  enc.confirmPassword("pass");

  Workbook workbook = new XSSFWorkbook();
  Sheet sheet = workbook.createSheet("sheet1");
  sheet.createRow(0).createCell(0).setCellValue(data);

  // write the workbook into the encrypted OutputStream
  OutputStream encos = enc.getDataStream(fs);
  workbook.write(encos);
  workbook.close();
  encos.close(); // this is necessary before writing out the FileSystem

  OutputStream os = new FileOutputStream("provawrite.xlsx");
  fs.writeFilesystem(os);
  os.close();
  fs.close();
 }

 public static void main(String[] args) throws Exception {
  doEncrypt("Test");
 }
}
...