java杂文系列(1) poi导出excel文件(包含图片)大的奇葩事件

最近负责的项目出现了个奇葩的问题,两个方法几乎同样的逻辑,模板也差不多,导出内容也差不多,但是导出的文件却相差10几兆,用户不能忍,我也不能忍,但是反复对比代码,反复推敲逻辑,硬是找不到个所以然。在百般摸索下最后发现了解决方案,但是根源还不是很清楚,知道的人还望不吝赐教。下面对解决的过程记录下,已备后续警示自己。

刚开始我是把文件中的图片复制到QQ里,然后再复制到桌面,然后看图片大小,发现图片都差不多,于是乎就排除里图片的可能。但是在同事的帮助下,我意识到这个思路有严重的问题,通过上述操作,我活生生的把12兆多的图片变成了60多K。于是乎顿然发现原来问题在图片上,于是采取正确的方式,先在导出的excel里把图片还原,然后将图片另存到另一个空的excel里,看图片的大小。(还原后再复制到QQ--》桌面 然后看大小也靠谱点)

确定是图片的问题了,分别调试两个方法发现下载图片的路径是一样的。下面是导出较大的excel的图片生成代码。其实通过调试图片后缀就是 .png 但是换种写法差距就是10几兆啊。

 

ImageIO.write(image, "png" , byteArray); 这句是关键只要把"png"改成suffix 就可以将导出文件从17兆降到1.4兆。问题是解决了,但是疑问还在,逻辑上想不通Why?
 

 

protected void toImage(Cell cell, String uri, ClientAnchor anchor) {
        if (uri == null) {
            return;
        }
	//新代码
        String suffix = FileUtils.getFileSuffix(uri).substring(1);
        int ptype = 0;
        if("png".equalsIgnoreCase(suffix)){
            ptype = Workbook.PICTURE_TYPE_PNG;
        }else if("jpg".equalsIgnoreCase(suffix) || "jpeg".equalsIgnoreCase(suffix)){
            ptype = Workbook.PICTURE_TYPE_JPEG;
        }else if("emf".equalsIgnoreCase(suffix)){
            ptype = Workbook.PICTURE_TYPE_EMF;
        }else{
            ptype = -1;
        }
        //新代码结束
        Drawing drawing = sheet.createDrawingPatriarch();
        
        try {
            ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
            BufferedImage image = ImageIO.read(new File(uri));
            //老代码
            /*ImageIO.write(image, "png" , byteArray);
            drawing.createPicture(anchor, getWorkBook().addPicture(byteArray   
                    .toByteArray(), Workbook.PICTURE_TYPE_PNG));*/
            //新代码
            ImageIO.write(image, suffix , byteArray);
            drawing.createPicture(anchor, getWorkBook().addPicture(byteArray.toByteArray() , ptype));
            //新代码结束
        } catch (IOException e) {
            e.printStackTrace();
        }
    }//新代码
        String suffix = FileUtils.getFileSuffix(uri).substring(1);
        int ptype = 0;
        if("png".equalsIgnoreCase(suffix)){
            ptype = Workbook.PICTURE_TYPE_PNG;
        }else if("jpg".equalsIgnoreCase(suffix) || "jpeg".equalsIgnoreCase(suffix)){
            ptype = Workbook.PICTURE_TYPE_JPEG;
        }else if("emf".equalsIgnoreCase(suffix)){
            ptype = Workbook.PICTURE_TYPE_EMF;
        }else{
            ptype = -1;
        }
        //新代码结束
        Drawing drawing = sheet.createDrawingPatriarch();
        
        try {
            ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
            BufferedImage image = ImageIO.read(new File(uri));
            //老代码
            /*ImageIO.write(image, "png" , byteArray);
            drawing.createPicture(anchor, getWorkBook().addPicture(byteArray   
                    .toByteArray(), Workbook.PICTURE_TYPE_PNG));*/
            //新代码
            ImageIO.write(image, suffix , byteArray);
            drawing.createPicture(anchor, getWorkBook().addPicture(byteArray.toByteArray() , ptype));
            //新代码结束
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

影响excel文件大小的因素:

 

1、可能版本不一样,高版本会小一点。
2、公式数量不一样。同样的内容,由公式计算出来的和复制粘贴值之后大小相差甚远,尤其是引用外部数据。
3、某些单元格设置有条件格式,只是没表现出来。
4、有隐藏的工作表标签。

当然内容还是主要的因素。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值