XSSFWorkbook编写时使用JDBC在Spring Boot应用程序中创建了损坏的.xlsx文档

时间:2018-07-03 09:31:23

标签: java excel apache-poi xssf

对于一个项目,我需要创建一个.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打开,并且大小只有4kb,而手动创建的文件会占用9kb,因此输出中一定缺少我未指定的内容吗?

我正在使用通过Gradle导入的Apache POI版本3.17

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 :(得分:3)

根据@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')

这会在Apache POI所使用的XML解析器的类路径中产生冲突,这意味着Excel部分需要在另一个项目中完成,并由Gradle处理依赖性问题。