当前位置: 首页 > article >正文

【java批量导出pdf】优化方案

问题情境:

项目中存在web页面点击一键导出,导出所有数据对应的pdf文件,由于有些pdf文件是实时生成的,之前最简答的写法for循环处理速度太慢,超过了nginx配置的最大响应时间了,且对用户交互体验上很不友好,所以进一步进行优化。

解决方案:

1.对大量的数据进行分段处理;(向上取余)
代码示例:

public List<List<FrApplyGuaranteeInfo>> segmentList(List<FrApplyGuaranteeInfo> list ,int segmentSize) {
        int limit = (list.size() + segmentSize - 1) / segmentSize;
        List<List<FrApplyGuaranteeInfo>> segmentList =
                Stream.iterate(0, n -> n + 1).limit(limit).parallel().map(a -> list.stream().
                        skip(a * segmentSize).limit(segmentSize).parallel().collect(Collectors.toList())).collect(Collectors.toList());
        return segmentList;
    }

2.通过threadPoolTaskExcetor.submit()方法进行多线程任务处理
示例代码:
第一步分段处理后的list

lists.forEach({list->{
   threadPoolExecutor.submit(new xxxxTask());
})

第二步:具体的task需要实现callalbe
示例代码如下:

@Slf4j
public class DownloadLetterZipTask implements Callable {
    
   // 需要预审的记录    
   private List<FrApplyGuaranteeInfo> dataList;
   private ZipOutputStream zipOutputStream;
   private CountDownLatch countDownLatch;
   private IFrApplyGuaranteeInfoService applyGuaranteeInfoService;
   public DownloadLetterZipTask(List<FrApplyGuaranteeInfo> dataList, ZipOutputStream zipOutputStream, CountDownLatch countDownLatch, IFrApplyGuaranteeInfoService applyGuaranteeInfoService)
   {    this.dataList = dataList;
       this.zipOutputStream = zipOutputStream;      
       this.countDownLatch = countDownLatch;      
       this.applyGuaranteeInfoService = applyGuaranteeInfoService;    }
    @Override
    public Object call() throws Exception {
       log.info("start--------------" + Thread.currentThread().getName());        
       try {           
           for (FrApplyGuaranteeInfo applyGuaranteeInfo : dataList) {
               if (!StringUtils.isEmpty(applyGuaranteeInfo.getAcceptNo())) {
                   try {
                       // 这一步为具体的将文件转为字节数组输出流
                       ByteArrayOutputStream waterOutputStream = applyGuaranteeInfoService.getLetterPdfByteStream(applyGuaranteeInfo.getAcceptNo());
                       byte[] xmpMetadata = waterOutputStream.toByteArray();
                       synchronized (zipOutputStream) {
                           zipOutputStream.putNextEntry(new ZipEntry(applyGuaranteeInfo.getGenerateeLetterNo() + ".pdf"));
                           zipOutputStream.write(xmpMetadata);
                           zipOutputStream.closeEntry();
                       }
                   } catch (Exception e) {
                       log.error("[一键导出]---acceptNo为{}生成pdf失败", applyGuaranteeInfo.getAcceptNo());
                   }
               }
           }
       } catch (Exception e) {
           e.printStackTrace();
           log.error("[xxxx]-批量下载zip失败");

       } finally {
           countDownLatch.countDown();
          }
       return null;
      }
   }

http://www.kler.cn/a/228241.html

相关文章:

  • 电路研究9.2——合宙Air780EP使用AT指令
  • Gin 学习笔记
  • Python装饰器的高级用法:动态装饰器与参数传递的深度解析
  • DAY6,使用互斥锁 和 信号量分别实现5个线程之间的同步
  • 工作~酒场指南
  • Ubuntu 20.04 x64下 编译安装ffmpeg
  • Liunx基本指令
  • 【PyRestTest】高级使用
  • Python循环语句——while循环的嵌套应用
  • 乐鑫与 Elektor 杂志合作推出特刊,聚焦 AIoT 创新
  • 神经网络基本原理
  • 部署私有知识库项目FastGPT
  • 图论练习3
  • vue绘制语音波形图---wavesurfer.js
  • 【Linux】进程间通信 --管道通信
  • JVM之Java内存区域
  • IP风险画像在企业网络安全中应用
  • freertos 源码分析一 list链表数据结构
  • 终端环境:zsh 和 oh-my-zsh
  • 【项目管理】CMMI-项目结项管理过程
  • Unity中blendtree和state间的过渡
  • 【Java万花筒】Java图形库探秘:创意编程、数据可视化与用户界面设计
  • 【Tomcat与网络9】提高Tomcat启动速度的八大措施
  • es6中标签模板
  • 大型软件编程实例分享,诊所门诊处方笺管理系统多台电脑同时使用的软件教程
  • 常用工具类-StringUtils