简体   繁体   中英

java.util.NoSuchElementException while writing image on Excel file using Apache poi 3.8 in java

I am getting below inconsistent exception when i call resize method. It fails 10% of time, because of below error. I can't reproduced it on my local environment.

java.util.NoSuchElementException
    at javax.imageio.spi.FilterIterator.next(ServiceRegistry.java:836)
    at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:528)
    at javax.imageio.ImageIO$ImageReaderIterator.next(ImageIO.java:513)
    at org.apache.poi.ss.util.ImageUtils.getImageDimension(ImageUtils.java:64)
    at org.apache.poi.xssf.usermodel.XSSFPicture.getImageDimension(XSSFPicture.java:278)
    at org.apache.poi.xssf.usermodel.XSSFPicture.getPreferredSize(XSSFPicture.java:203)
    at org.apache.poi.xssf.usermodel.XSSFPicture.resize(XSSFPicture.java:170)
    at org.apache.poi.xssf.usermodel.XSSFPicture.resize(XSSFPicture.java:152)

Please suggest any root cause.

The code snippet which i have written as follows

Sheet sheet2 = workbook.createSheet("Graph");
            //feedChartToExcel = new FileInputStream("C:\\Users\\idnyob\\Desktop\\PcrChartImageFogX7eRH4c1551955300676.png");
            feedChartToExcel = new FileInputStream(this.imagePath);

            // Convert picture to be added into a byte array
            byte[] bytes = IOUtils.toByteArray(feedChartToExcel);


            // Add Picture to Workbook, Specify picture type as PNG and Get an Index
            int pictureId = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
            // Close the InputStream. We are ready to attach the image to workbook now
            feedChartToExcel.close();
            // Create the drawing container
            XSSFDrawing drawing = (XSSFDrawing) sheet2.createDrawingPatriarch();
            //  Create an anchor point
            XSSFClientAnchor anchor = new XSSFClientAnchor();
            //  Define top left corner, and we can resize picture suitable from there
            anchor.setCol1(2);
            anchor.setRow1(1);
            // Invoke createPicture and pass the anchor point and ID
            XSSFPicture picture = drawing.createPicture(anchor, pictureId);
            // Call resize method, which resizes the image
            picture.resize();

Because the question was about the root cause of that exception, here is the answer:

org.apache.poi.ss.util.ImageUtils.getImageDimension does the following:

If the given type is either Workbook.PICTURE_TYPE_JPEG or Workbook.PICTURE_TYPE_PNG or Workbook.PICTURE_TYPE_DIB , then it uses javax.imageio.ImageIO for creating a ImageInputStream from the given InputStream . Then it gets a Iterator of possible ImageReader s for that ImageInputStream . And then it does the wrong. It calls Iterator.next to get the first possible ImageReader without checking whether the Iterator has a next element at all. That trows java.util.NoSuchElementException if there is not a next element in Iterator .

But why there is not a next element in Iterator ? Since there is only one call Iterator.next at all, there is not even one ImageReader in the Iterator . The Iterator has not even one element. But that means, that javax.imageio.ImageIO was not able finding a currently registered ImageReader that claim to be able to decode the supplied ImageInputStream . And that means that either the given InputStream was not an InputStream from jpeg , png or bmp picture or there is no currently registered ImageReader that claim to be able to decode jpeg , png or bmp pictures properly.

Since it fails only inconsistent in other environments and never fails in OP's local environment, the first option is inapplicable. So my suspicion is that, if it fails, there is no currently registered ImageReader that claim to be able to decode jpeg , png or bmp pictures properly. So what I would do is:

First: Determining using what picture type it fails ( jpeg , png or bmp ).

Second: Determining in what environment it fails (operating system, Java version, used frameworks, ...).

The apache poi version is not relevant since even apache poi 4.0.1 does the same wrong call to Iterator.next without checking Iterator.hasNext first: org.apache.poi.ss.util.ImageUtils.getImageDimension .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM