使用POI 3.7 实现操作Excel,是实现一个报告的生成与审批。
首先,在报告生成的时候,通过读取Excel报告模版,然后向Excel中插入数据与图片。
插入数据没有问题,插入图片也没有问题代码如下:
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
图片是从数据库中blob字段中取出的。调用下面方法完成向sheet中插入图片。
/**
 * 插入某个图片到指定索引的位置
 * @param HSSFWorkbook wb; Workbook对象
 * @param int sheetIndex; 插入图片的sheet下标索引
 * @param byte[] data; 图片字节流
 * @param int startRow; 起始行
 * @param int startColumn; 起始列
 * @param int upRow; 截至行
 * @param int upColumn; 截至列
 * @param int index; 内缩进像素数
 */
public static void insertImage(HSSFWorkbook wb,HSSFPatriarch patriarch,Blob blob,int startRow,int startColumn,int upRow,int upColumn,int index){
int dx1=0,dy1=0,dx2=0,dy2=0;
if(index!=0){
dx1 = index*16;
dy1 = index*16;
dx2 = 1024-index*16;
dy2 = 256-index*16;
upRow = upRow-1;
upColumn = upColumn -1;
}
      
         HSSFClientAnchor anchor = new HSSFClientAnchor(dx1,dy1,dx2,dy2,(short)startColumn,startRow,(short)upColumn,upRow);
         anchor.setAnchorType(2);
         patriarch.createPicture(anchor , wb.addPicture(getImageData(blob, "JPEG"),HSSFWorkbook.PICTURE_TYPE_JPEG));
     }

//从图片里面得到字节数组
public static  byte[] getImageData(Blob blob,String imageType){
        try{
         BufferedImage bi=ImageIO.read(blob.getBinaryStream());
             ByteArrayOutputStream bout=new ByteArrayOutputStream();
             ImageIO.write(bi,imageType,bout);
            return bout.toByteArray();
         }catch(Exception exe){
             exe.printStackTrace();
            return null;
         }
     }
生成好的报告,保存到数据库中blob字段,在审批过程中,从blob字段中取出来查看,文件中数据显示与图片显示都是没有问题的。
在审核处理之后,需要再次向该报告文件中增加部分图片,图片格式也是JPG,就出现问题。
问题是从数据库中Blob字段中取出对其进行增加图片操作,如果
HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); 再次这样创建一个HSSFPatriarch 对象来向sheet中添加图片的话,新添加的图片可以正常显示,但是之前的所有图片都不能显示,原本图片上提示红X,显示内容“无法显示图像,计算机可能没有足够的内存以打开图像,也可能是该图像已损坏。......”。这个我明白是因为再次同一个sheet中创建了HSSFPatriarch 对象,之前的图片就不能显示。
如果,我用HSSFPatriarch patriarch = sheet.getDrawingPatriarch();然后向sheet中添加图片,新添加的图片就依次显示原有图片,比如,原有10张图片,而本次新添加了3张图片,则新增添加的3张图片并不是所添加的对应图片,依次显示为excel文件中原有图片的前3张,而原有图片的前3张就不能正常显示,错误为上面所阐述的红X加提示信息。
各位,有遇到类似问题的解决方式,请倾囊相授,不甚感激,分不够可以再加。 

解决方案 »

  1.   

    经反复测试与查找,与数据库存储Blob字段没有关系,还是
    HSSFPatriarch patriarch = sheet.getDrawingPatriarch();

     patriarch.createPicture(anchor , wb.addPicture(getImageData(blob, "JPEG"),HSSFWorkbook.PICTURE_TYPE_JPEG));
    添加图片时,感觉是没有创建图片对象,还是引用了sheet的patriarch对象中已存在的图片对象,造成了新增图片显示为已存在图片,而对应的已存在图片无法显示。由于本人对HSSFPatriarch 不慎了解,不知道有没有其他接口来处理这种添加图片的需要。
      

  2.   

    这个问题 是因为 HSSFPatriarch patriarch = sheet.getDrawingPatriarch();
     这个对象只能创建一次 
      

  3.   

    不知你的问题有没有解决,我也遇到此问题,已经解决,最新版的POI3.9已经解决此问题。
    52272 - [PATCH] Inserting images on cloned sheet with images. (poi-developers)
      

  4.   

    应该是POI的BUG,往Excel里添加新批注时,也会导致原批注丢失。