Apache-POI не сохраняет книгу Excel даже после выполнения fileoutputstream.close () - PullRequest
0 голосов
/ 29 мая 2019

Я пытаюсь создать новые файлы Excel на основе общего шаблона. Я открываю файл шаблона Excel, редактирую его и сохраняю в новом месте. Для записи файла я использую FileOutputStream и закрываю поток после записи, чтобы сохранить его. Весь процесс работает правильно, но созданный файл Excel не сохраняется должным образом. Мой файл шаблона имеет 35 КБ, и мой недавно созданный файл Excel показывает только 30 КБ. Когда я открываю только что созданный файл Excel, я вижу записанные данные, и мне нужно сохранить их и закрыть, чтобы отобразить правильный размер 36 КБ.
Новые экземпляры должны быть загружены во внешнее приложение, которое показывает «данные не найдены» при прямой загрузке 30 КБ, несохраненного Excel, тогда как сохраненный файл 36 КБ успешно загружает файл.

Я пробовал разные способы, предлагаемые в интернете, чтобы делать то же самое, и ни один из них не генерировал правильные файлы Excel. Я использую Java 1.7 и Apache-Poi версии 3.17.

Ниже приведен пример моего кода: -

public void createExcelFiles() throws ParseException, IOException {

    File file = new File(ExcelTemplatePath);
    FileInputStream fip = new FileInputStream(file);
    FileOutputStream fos = new FileOutputStream(excelOutputFile);

    XSSFWorkbook workbookOld = new XSSFWorkbook(fip);
    try (SXSSFWorkbook workbook = new SXSSFWorkbook(workbookOld, rowAccessWindowSize)) {

        if (makeLargeFiles) {
            SXSSFSheet sheet = (SXSSFSheet) workbook.getSheetAt(0);
            makeExcelFile.makeLargeFile(sheet);
            workbook.write(fos);
        } else {
            Sheet sheet = workbookOld.getSheetAt(0);
            makeExcelFile.makeNormalFile(sheet);
            workbookOld.write(fos);

        }
        fos.close();
        fip.close();
        workbook.close();
    }
    workbookOld.close();

}

Ответы [ 2 ]

0 голосов
/ 30 мая 2019

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

Рабочая книга SXSSFWorkbook = новая книга SXSSFWorkbook (workbookOld, rowAccessWindowSize, true, true)

Второй истинный параметр предназначен для использования общих строк. Использование этого свойства делает данные видимыми для внешнего приложения без необходимости открывать и сохранять их снова. Однако проблема размера все еще остается, и почему использование общих строк все еще неясно. Для получения дополнительной информации о проверке общей строки this out.

0 голосов
/ 29 мая 2019

Обернутые потоки ввода / вывода, такие как XSSFWorkbook, должны сначала закрыться, возможно, все еще записывая эпилог в обернутый OutputStream.И низкоуровневый поток может быть закрыт.

Имейте в виду, что некоторые классы обертывания сами закроют обернутый поток внутри своих собственных close.

Поскольку попытка с ресурсами идеальна, для закрытия также в случае исключения, окончательная версия будет выглядеть так:

public void createExcelFiles() throws ParseException, IOException {
    File file = new File(ExcelTemplatePath);
    try (FileInputStream fip = new FileInputStream(file);
            FileOutputStream fos = new FileOutputStream(excelOutputFile);
            XSSFWorkbook workbookOld = new XSSFWorkbook(fip);
            SXSSFWorkbook workbook = new SXSSFWorkbook(workbookOld, rowAccessWindowSize)) {

        if (makeLargeFiles) {
            SXSSFSheet sheet = (SXSSFSheet) workbook.getSheetAt(0);
            makeExcelFile.makeLargeFile(sheet);
            workbook.write(fos);
        } else {
            Sheet sheet = workbookOld.getSheetAt(0);
            makeExcelFile.makeNormalFile(sheet);
            workbookOld.write(fos);

        }
    }
    // Doing in reverse order of declaration:
    // 1. workbook.close();
    // 2. workbookOld.close();
    // 3. fos.close();
    // 4. fip.close();
}

В вашем коде произошло обращение, и закрытие произошло явным образом и с помощью try-with-resources.

...