7

I try to create Excel Pivot Table using Apache POI.
At the moment, when I try to write data in a workbook workbook.write(fileOut); I get exception

org.apache.poi.ooxml.POIXMLException: java.io.EOFException: Unexpected end of ZLIB input stream

There is the code of the class:

public class PivotTable {



public static void createPivotTable(String pathToWorkbook, String sheetName) throws IOException {

    Workbook workbook = new XSSFWorkbook(pathToWorkbook);

    XSSFSheet sheet = (XSSFSheet) workbook.getSheet(sheetName);

    int firstRowInd = sheet.getFirstRowNum();
    int lastRowInd = sheet.getLastRowNum();
    int firstCellInd = sheet.getRow(0).getFirstCellNum();
    int lastCellInd = sheet.getRow(0).getLastCellNum() - 1;

    //Specifying top left ant the bottom right of the table data
    CellReference topLeft = new CellReference(firstRowInd, firstCellInd);
    CellReference botRight = new CellReference(lastRowInd, lastCellInd);

    //The area of data in table
    AreaReference aref = new AreaReference(topLeft, botRight, SpreadsheetVersion.EXCEL2007);

    //Position of the pivot table
    CellReference pos = new CellReference(firstRowInd + 4, lastCellInd + 1);

    //Creating the pivot table
    XSSFPivotTable pivotTable = sheet.createPivotTable(aref, pos);


    pivotTable.addRowLabel(0);
    pivotTable.addRowLabel(2);
    pivotTable.addColLabel(3);

    FileOutputStream fileOut = new FileOutputStream(pathToWorkbook);
    workbook.write(fileOut);
    fileOut.close();


}

And there is the StackTrace of Exception:

Exception in thread "main" org.apache.poi.ooxml.POIXMLException: java.io.EOFException: Unexpected end of ZLIB input stream
    at org.apache.poi.ooxml.POIXMLDocument.getProperties(POIXMLDocument.java:147)
    at org.apache.poi.ooxml.POIXMLDocument.write(POIXMLDocument.java:240)
    at PivotTable.createPivotTable(PivotTable.java:50)
    at Main.main(Main.java:14)
Caused by: java.io.EOFException: Unexpected end of ZLIB input stream
    at java.util.zip.InflaterInputStream.fill(InflaterInputStream.java:240)
    at org.apache.commons.compress.archivers.zip.InflaterInputStreamWithStatistics.fill(
InflaterInputStreamWithStatistics.java:52)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:158)
    at org.apache.commons.compress.archivers.zip.InflaterInputStreamWithStatistics.read(
InflaterInputStreamWithStatistics.java:67)
    at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:122)
    at org.apache.commons.compress.archivers.zip.InflaterInputStreamWithStatistics.read(
InflaterInputStreamWithStatistics.java:58)
    at java.io.FilterInputStream.read(FilterInputStream.java:83)
    at org.apache.poi.openxml4j.util.ZipArchiveThresholdInputStream.read(ZipArchiveThresholdInputStream.java:69)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager$RewindableInputStream.read(XMLEntityManager.java:2890)
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:674)
    at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(XMLVersionDetector.java:148)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:805)
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:770)
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
    at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3414)
    at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1272)
    at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1259)
    at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345)
    at org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument$Factory.parse(Unknown Source)
    at org.apache.poi.ooxml.POIXMLProperties.(POIXMLProperties.java:81)
    at org.apache.poi.ooxml.POIXMLDocument.getProperties(POIXMLDocument.java:145)
    ... 3 more
Mike
  • 706
  • 7
  • 16

3 Answers3

15

I had the same issue, I solved it by changing the line:

Workbook workbook = new XSSFWorkbook(pathToWorkbook);

to:

Workbook workbook = new XSSFWorkbook(new FileInputStream(pathToWorkbook));

Hope it helps! :)

  • The downside of this answer is that the Apache POI documentation recommends using File over FileInputStream because FileInputStream is more memory intensive. But the behavior being observed in this question, which appears to be a defect in Apache POI, prevents using File when modifying existing documents. – denver Oct 11 '22 at 16:07
9

Pretty sure the problem is you overwriting the file. Try to save to a different path. If you still want to overwrite the file, save to something else, delete the original, then rename the file you wrote into place:

try (FileOutputStream fileOut = new FileOutputStream(pathToWorkbook + ".new")) {
    workbook.write(fileOut);
}
Files.delete(Paths.get(pathToWorkbook));
Files.move(Paths.get(pathToWorkbook + ".new"), Paths.get(pathToWorkbook));
rzwitserloot
  • 85,357
  • 5
  • 51
  • 72
  • I tried it. The new file with all sheets was created and it works, but I got "Exception in thread "main" java.nio.file.FileAlreadyExistsException: samples\Sample Tables New.xlsx -> samples\Sample Tables.xlsx" when I tried to Files.move() – Андрей Суручану Sep 18 '18 at 15:56
  • for resolving this problem I just renamed file using this stings `new File(pathToWorkbook).renameTo(new File("tmpName.xlsx")); Files.delete(Paths.get("tmpName.xlsx"));` – Андрей Суручану Sep 18 '18 at 16:58
2

It seems there is a little bug in workbook.write() method. I found 2 workarounds. First is to specify any another (dummy) file name for FileOutputStream. When workbook closes both files will be filled. Second, and more good, is to specify dummy OutputStream for workbook.write() method:

OutputStream dummyOutputStream = new OutputStream() {
            @Override
            public void write(int b) throws IOException {

            }
        };
        workbook.write(dummyOutputStream);
        dummyOutputStream.close();
        workbook.close();
Valeriy K.
  • 2,616
  • 1
  • 30
  • 53
  • This does not appear to be a solution. Using a dummy file stream resulted in the file being unmodified. As such changes to the file were not written out. – denver Oct 11 '22 at 15:57