大数据量excel含图片导出解决方案

前言

公司存在很多excel含图片导出,因为提供给客户的excel可能还会打印出来,所以图片不能存链接。真坑!!!

一步步解决原理

  1. 使用这个SXSSFWorkbook进行excel导出,不了解的可以看我的这个博客

    你一定没用过最简单的使用SXSSFWorkbook快速导出百万条数据

  2. 异步导出

    1. 使用异步导出方式,用户点击导出后后台自动运行导出,无需用户等待,然后有个任务列表,导出完成后用户可以回来点开下载
  3. 压缩导出

    1. 建议压缩图片导出:因为压缩图片后导出可以支撑更多的数据量,但还是因服务器内存而定。
    2. 不建议不压缩导出:因不压缩图片的数据量巨大,特别能吃内存。可能会导不出,不建议使用
  4. SXSSFWorkbook图片没缓存在磁盘上

    1. 因为我们都知道SXSSFWorkbook有个操作窗口,默认100条数据在内存,多余的数据会缓存在磁盘中,追加图片的源码

      public int addPicture(byte[] pictureData, int format) {
              
              
          // 获取所有图片
              int imageNumber = getAllPictures().size() + 1;
              XSSFPictureData img = (XSSFPictureData)createRelationship(XSSFPictureData.RELATIONS[format], XSSFFactory.getInstance(), imageNumber, true);
              try {
              
              
                  OutputStream out = img.getPackagePart().getOutputStream();
                  out.write(pictureData);
                  out.close();
              } catch (IOException e){
              
              
                  throw new POIXMLException(e);
              }
              pictures.add(img);
              return imageNumber - 1;
          }
      
      	/**
           * Gets all pictures from the Workbook.
           *
           * @return the list of pictures (a list of {@link XSSFPictureData} objects.)
           * @see #addPicture(byte[], int)
           */
          public List<XSSFPictureData> getAllPictures() {
              
              
              if(pictures == null){
              
              
                  List<PackagePart> mediaParts = getPackage().getPartsByName(Pattern.compile("/xl/media/.*?"));
                  pictures = new ArrayList<XSSFPictureData>(mediaParts.size());
                  for(PackagePart part : mediaParts){
              
              
                      pictures.add(new XSSFPictureData(part, null));
                  }
              }
              return pictures; //YK: should return Collections.unmodifiableList(pictures);
          }
      
      	/**
           * excel中追加的图片以XSSFPictureData对象,存在内存中
           */
          private List<XSSFPictureData> pictures;
      
  5. 分页导出

    1. 缘由:即便是压缩导出,仍存在上限。假设每条记录含9张图片,每张图片大小为100k。一条记录算1mb,1000条数据基本占1g内存,而你的服务运行内存也就1g,也就说压缩最多导1000条就撑死了。
    2. 引出:既然一个excel承载不了这么多,那就把它拆成多个导出excel,比如200条一个excel,最后将生成的多个excel压缩成一个压缩包提供给用户下载。
    3. 结论:分页导出功能生成的压缩包里是多个较小的excel。因为即便导出一个很大的excel给到用户也没有意义,因为这跟打不开。多个较小可以较为流畅的打开。可以承载更大数据量,理论上磁盘有多大,就可以存多少excel。

终极

大量图片数据导出为excel导致内存溢出解决方案落地

猜你喜欢

转载自blog.csdn.net/weixin_41187876/article/details/112396220