大数据量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导致内存溢出解决方案落地

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java导出数据到Excel时,可能会因为数据过大导致前端请求超时。这是由于以下几个原因引起的: 1. 数据大:导出数据需要较长的处理时间和较高的系统资源消耗。如果数据远远超过前端请求能承受的极限,前端请求时间可能超出设置的时间限制,从而导致超时。 2. 网络传输限制:在数据较大的情况下,数据的传输时间也会相应增加。如果网络传输速度慢或网络连接不稳定,请求可能会在传输过程超时。 为了解决这个问题,可以考虑以下几个方案: 1. 分批导出:将大数据分成小批次进行导出。可以在前端通过多次请求来获取分批次的数据,然后在后台进行数据导出。这样可以避免单次请求时间过长导致的超时问题。 2. 后台异步导出:当前端发起数据导出请求时,后台可以先返回一个任务标识,告知前端任务已经在后台进行处理。后台将数据导出的过程放在一个异步任务执行,不会阻塞前端请求。前端可以轮询任务状态,直到任务完成并提供下载链接。 3. 压缩文件导出:将导出的数据以压缩文件的形式返回给前端,可以减小数据的传输,加快数据传输速度。前端可以在接收到文件后再进行解压和处理。 4. 前端分页获取:前端可以通过分页的方式获取数据,每次请求只获取一页的数据。这样可以减少单次请求的数据,降低请求超时的风险。 通过上述方案,可以有效地解决Java导出Excel数据大导致前端请求超时的问题,提高系统的可用性和用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值