При написании XSSFWorkbook создает поврежденный документ .xlsx в приложении Spring Boot с использованием JDBC - PullRequest
0 голосов
/ 03 июля 2018

Для проекта мне нужно создать документ .xlsm excel, автоматически заполняющий файл шаблона. Проблема в том, что вывод поврежден и не может быть прочитан Excel 365 или Apache POI.

Я разобрал его до следующего минимального примера, который можно запустить методом main. Для полной безопасности используется формат .xlsx.

public static void main(String[] args) {
    XSSFWorkbook document = new XSSFWorkbook();
    XSSFSheet spreadsheet = document.createSheet("Test");
    spreadsheet.createRow(0).createCell(0).setCellValue("Testie test");

    // Output .xlsx file
    FileOutputStream stream;
    try {
        stream = new FileOutputStream("test_output.xlsx");
        document.write(stream);
        stream.flush();
        stream.close();

    } catch (IOException e) {
        System.err.println("Error" + e.getMessage());
        e.printStackTrace();
    }
    ...

Созданный файл test_output.xlsx не может быть открыт в Excel 365 и имеет размер всего 4 КБ, в то время как созданный вручную файл займет 9 КБ, поэтому в выводе должно быть что-то отсутствующее, которое я не указал?

Я использую Apache POI версии 3.17, импортированный через Gradle, используя

compile('org.apache.poi:poi-ooxml:3.17')

, а также с Apache POI версии 3.13 с версией до 2016 года. В обоих случаях не повезло.

Когда метод main расширяется, чтобы открыть тот же файл, который был только что создан, как показано ниже

    ...
    // Try to read it again
    try {
        document = new XSSFWorkbook("test_output.xlsx");
        System.out.println(document.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());

     } catch (IOException e) {
         e.printStackTrace();
     }
}

тогда я попаду в следующее исключение

java.io.IOException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Can't read content types part !
    at org.apache.poi.POIXMLDocument.openPackage(POIXMLDocument.java:91)
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:340)
    ...

Если, с другой стороны, все XSSF* заменены на HSSF*, а тип файла превращен в файл .xls, то выводимый документ в порядке, но мне нужно создать рабочий документ Excel 365, а не Excel 2003 один.

Ниже приведен файл [Content_Types].xml в документе .xlsx, сделанном вручную

.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
    <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
    <Default Extension="xml" ContentType="application/xml"/>
    <Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
    <Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
    <Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
    <Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
    <Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
    <Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
    <Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
</Types>

Пока в файле, созданном POI, указано [Content_Types].xml .xlsx

<?xml version = '1.0' encoding = 'UTF-8' standalone = 'yes'?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
    <Default ="rels"/>
    <Default ="xml"/>
    <Override ="/docProps/app.xml"/>
    <Override ="/docProps/core.xml"/>
    <Override ="/xl/sharedStrings.xml"/>
    <Override ="/xl/styles.xml"/>
    <Override ="/xl/workbook.xml"/>
    <Override ="/xl/worksheets/sheet1.xml"/>
</Types>

1 Ответ

0 голосов
/ 03 июля 2018

Исходя из предложений @AxelRichter, когда все другие зависимости удаляются в build.gradle, тогда [Content_Types] .xml выглядит следующим образом.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
    <Default ContentType="application/vnd.openxmlformats-package.relationships+xml" Extension="rels"/>
    <Default ContentType="application/xml" Extension="xml"/>
    <Override ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml" PartName="/docProps/app.xml"/>
<Override ContentType="application/vnd.openxmlformats-package.core-properties+xml" PartName="/docProps/core.xml"/>
    <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml" PartName="/xl/sharedStrings.xml"/>
    <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" PartName="/xl/styles.xml"/>
    <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" PartName="/xl/workbook.xml"/>
    <Override ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" PartName="/xl/worksheets/sheet1.xml"/>
</Types>

И приведенный выше код работает без проблем, и файл можно открыть в Office 365. Проблема заключается в импорте

compile('com.oracle.jdbc:ojdbc8:12.2.0.1')

Это создает конфликт в пути к классам для синтаксического анализатора XML, используемого Apache POI, что означает, что либо часть Excel должна быть выполнена в другом проекте с Gradle, обрабатывающим проблемы зависимостей.

...