Обновление и шифрование существующего файла xlsx с помощью Apache POI - PullRequest
0 голосов
/ 12 июня 2018

У меня есть электронная таблица xlsx.Я использую Apache POI 3.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 Ответ

0 голосов
/ 13 июня 2018

Проблема здесь заключается в несоответствии в фиксации изменений между XSSFWorkbook и OPCPackage.Изменения в XSSFWorkbook будут зафиксированы в OPCPackage только при XSSFWorkbook.write.Поэтому, если вы не (или не можете) записать XSSFWorkbook, OPCPackage останется без изменений.

С другой стороны, если вы записываете XSSFWorkbook, он всегда фиксирует изменения в OPCPackage, из которого была создана рабочая книга.Таким образом, если это был OPCPackage, созданный из File, то этот файл всегда обновляется до того, как книга будет записана в другой файл.Это тоже раздражает.

Так что, по моему мнению, у него нет возможности программно влиять на процесс фиксации между 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();

 }
}
...