简体   繁体   English

在Java中使用Apache Poi 3.8在Excel文件上写入图像时出现java.util.NoSuchElementException

[英]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. 当我调用resize方法时,我遇到了不一致的异常。 It fails 10% of time, because of below error. 由于出现以下错误,它失败了10%的时间。 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: org.apache.poi.ss.util.ImageUtils.getImageDimension执行以下操作:

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 . 如果给定类型是Workbook.PICTURE_TYPE_JPEGWorkbook.PICTURE_TYPE_PNGWorkbook.PICTURE_TYPE_DIB ,则它将使用javax.imageio.ImageIO从给定InputStream创建ImageInputStream Then it gets a Iterator of possible ImageReader s for that ImageInputStream . 然后,它为该ImageInputStream获取可能的ImageReaderIterator 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. 它调用Iterator.next来获得第一个可能的ImageReader而无需检查Iterator是否具有下一个元素。 That trows java.util.NoSuchElementException if there is not a next element in Iterator . 如果Iterator没有下一个元素,则抛出java.util.NoSuchElementException

But why there is not a next element in Iterator ? 但是,为什么Iterator没有下一个元素? Since there is only one call Iterator.next at all, there is not even one ImageReader in the Iterator . 由于只有一个呼叫Iterator.next可言,甚至没有一个ImageReaderIterator The Iterator has not even one element. Iterator甚至没有一个元素。 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 . 但这意味着javax.imageio.ImageIO无法找到当前注册的ImageReader ,声称它能够解码提供的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. 这意味着给定的InputStream不是来自jpegpngbmp图片的InputStream ,或者当前没有注册的ImageReader声称能够正确解码jpegpngbmp图片。

Since it fails only inconsistent in other environments and never fails in OP's local environment, the first option is inapplicable. 由于它只会在其他环境中不一致而失败,而不会在OP的本地环境中失败,因此第一个选项不适用。 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. 因此,我怀疑如果失败,则当前没有注册的ImageReader声称能够正确解码jpegpngbmp图片。 So what I would do is: 所以我要做的是:

First: Determining using what picture type it fails ( jpeg , png or bmp ). 首先:确定使用哪种图片类型失败( jpegpngbmp )。

Second: Determining in what environment it fails (operating system, Java version, used frameworks, ...). 第二:确定在什么环境下会失败(操作系统, Java版本,使用的框架等)。

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 . apache poi版本不相关,因为甚至apache poi 4.0.1都对Iterator.next进行了相同的错误调用,而没有先检查Iterator.hasNextorg.apache.poi.ss.util.ImageUtils.getImageDimension

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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