最近负责的项目出现了个奇葩的问题,两个方法几乎同样的逻辑,模板也差不多,导出内容也差不多,但是导出的文件却相差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、有隐藏的工作表标签。
当然内容还是主要的因素。