欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 美景 > 使用@FunctionalInterface进行异步导出Excel数据

使用@FunctionalInterface进行异步导出Excel数据

2025/5/14 11:51:23 来源:https://blog.csdn.net/Katharsis_2021/article/details/144963679  浏览:    关键词:使用@FunctionalInterface进行异步导出Excel数据

项目场景:

项目中需要使用Excel导出大量数据,首先要进行大量的查询,但是由于数据量太大,导出的时候会让前端在pending,所以需要使用异步的方式先让前端返回。


解决方案:

使用@FunctionalInterface方式来进行异步导出。

首先,我们来确定函数式接口在哪里

@FunctionalInterface
public interface ExportDataQueryInterface {List<?> queryExportData();}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class SheetInfoBean2 {/*** sheet页名称*/private String sheetName;/*** sheet标题bean*/private Class<?> headClass;/*** sheet页数据*/private ExportDataQueryInterface dataList;
}

如代码所示,函数式接口隐藏在SheetInfoBean中,我们在通过异步方法调用Bean时,函数式接口的作用就是执行耗时较长的查询。也就是说,把不同的查询方法作为参数包裹进异步方法中。从而达到查询,导出异步的结果。

这里则是实际执行导出的方法

@Overridepublic void exportToExcelFileAsync(Map<String,Object> context, TaskModule exportType,List<SheetInfoBean2> sheetInfoBeans) {String fileName = exportType.getDescription()+"-"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date())+".xlsx";TaskDto taskDto = new TaskDto();taskDto.setFileName(fileName);taskDto.setType(TaskTypeEnum.EXPORT);taskDto.setTaskState(TaskStateEnum.EXECUTE);taskDto.setTaskModule(exportType);Long taskId = taskClient.add(taskDto);taskDto.setId(taskId);SpringUtils.getBean(ExcelExportService.class).exportToExcelFileAsync(taskDto,context,sheetInfoBeans);}

异步执行,lambda在这里开始真正执行。因为这里调用了SheetInfobeans

@Async@Overridepublic void exportToExcelFileAsync(TaskDto taskDto, Map<String, Object> context, List<SheetInfoBean2> sheetInfoBeans){ThreadContext.set(context);String filePath = System.getProperty("java.io.tmpdir")+taskDto.getFileName();File file = new File(filePath);FileInputStream fileInputStream = null;try{//创建excel文件ExcelWriter excelWriter = EasyExcel.write(filePath).build();WriteSheet writeSheet;for (SheetInfoBean2 bean : sheetInfoBeans) {List<?> list = bean.getDataList().queryExportData();// 构建sheet对象writeSheet = EasyExcel.writerSheet(bean.getSheetName()).head(bean.getHeadClass()).build();// 写出sheet数据excelWriter.write(list, writeSheet);}excelWriter.close();fileInputStream = new FileInputStream(filePath);//更新状态UploadResp upload = fileClient.upload(new MockMultipartFile(file.getName(),file.getName(), ContentType.APPLICATION_OCTET_STREAM.toString(),fileInputStream), null, BizType.EXPORT.getName());Long fileId = upload.getFileId();taskDto.setFileId(fileId);taskDto.setSize(file.length());taskDto.setTaskState(TaskStateEnum.FINISHED);taskClient.update(taskDto);}catch (Exception e){log.error(e.getMessage(),e);}finally {if(file.exists()){file.deleteOnExit();}if(fileInputStream != null){try {fileInputStream.close();} catch (IOException e) {log.error(e.getMessage(),e);}}ThreadContext.clear();}}

Lambda 表达式的执行:
当 bean.getDataList().queryExportData() 被调用时,才会触发 Supplier<List<?>> 中的 Lambda 表达式执行。也就是说,Lambda 表达式是在这里开始执行的。

使用示例:

excelExportService.exportToExcelFileAsync(ThreadContext.get(),TaskModule.COUPON_RECORD,List.of(new SheetInfoBean2("优惠券记录", CouponRecordExcelDto.class, (() -> {return SpringUtils.getBean(this.getClass()).query(params, pageRequest).getContent().stream().map(genericDto -> {Map<String, Object> flattenedFields = genericDto.getFlattenedFields();return BeanUtil.copyProperties(flattenedFields, CouponRecord.class);}).collect(Collectors.toList());}))));}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词