Excel高性能异步导出完整方案!

news/2025/10/27 17:42:55/文章来源:https://www.cnblogs.com/12lisu/p/19169750

前言

在大型电商系统中,数据导出是一个高频且重要的功能需求。

传统的同步导出方式在面对大数据量时往往会导致请求超时、内存溢出等问题,严重影响用户体验。

苏三商城项目创新性地设计并实现了一套完整的Excel异步导出机制,通过注解驱动、任务队列、定时调度、消息通知等技术手段,完美解决了大数据量导出的技术难题,成为项目的重要技术亮点。

系统架构设计

整体架构图

e5a78da6-6b82-40f7-9573-d00aa7dcd0d7 (1)

核心组件说明

  1. 注解驱动层:通过@ExcelExport注解实现声明式编程
  2. 切面处理层CommonTaskAspect负责拦截和任务创建
  3. 任务管理层ExcelExportTask执行具体的导出逻辑
  4. 调度引擎层:基于Quartz的定时任务调度
  5. 消息通知层:RocketMQ + WebSocket实现异步通知
  6. 存储层:MySQL存储任务状态,OSS存储导出文件

异步导出流程详解

完整流程图

505c0b6a-9d51-4064-9361-9ce57347715e (1)

关键步骤分析

1. 注解驱动任务创建

@ExcelExport(ExcelBizTypeEnum.USER)
@ApiOperation(notes = "导出用户数据", value = "导出用户数据")
@PostMapping("/export")
public void export(HttpServletResponse response, UserConditionEntity userConditionEntity) {// 方法体可以为空,切面会自动处理
}

设计亮点

  • 声明式编程:通过注解实现功能声明,代码简洁
  • 零侵入性:业务方法无需修改,切面自动处理
  • 类型安全:通过枚举确保业务类型的正确性

2. 切面拦截与任务创建

@Aspect
@Component
public class CommonTaskAspect {@Before("@annotation(cn.net.susan.annotation.ExcelExport)")public void before(JoinPoint joinPoint) throws Throwable {// 获取注解信息ExcelBizTypeEnum excelBizTypeEnum = method.getAnnotation(ExcelExport.class).value();// 创建任务实体CommonTaskEntity commonTaskEntity = createCommonTaskEntity(excelBizTypeEnum);// 保存任务到数据库commonTaskMapper.insert(commonTaskEntity);}
}

技术特色

  • AOP切面编程:实现横切关注点的分离
  • 反射机制:动态获取注解信息和方法参数
  • 任务持久化:将任务信息保存到数据库,确保可靠性

3. 定时任务调度机制

@Component
public class CommonTaskJob extends BaseJob {@Overridepublic JobResult doRun(String params) {// 查询待执行任务CommonTaskConditionEntity condition = new CommonTaskConditionEntity();condition.setStatusList(Arrays.asList(TaskStatusEnum.WAITING.getValue(),TaskStatusEnum.RUNNING.getValue()));List<CommonTaskEntity> tasks = commonTaskMapper.searchByCondition(condition);// 执行任务for (CommonTaskEntity task : tasks) {AsyncTaskStrategyContextFactory.getInstance().getStrategy(task.getType()).doTask(task);}return JobResult.SUCCESS;}
}

核心机制

  • 定时扫描:通过Quartz定时扫描任务队列
  • 策略模式:根据任务类型选择对应的处理器
  • 并发处理:支持多个任务并发执行

4. 异步任务处理器

@AsyncTask(TaskTypeEnum.EXPORT_EXCEL)
@Service
public class ExcelExportTask implements IAsyncTask {@Overridepublic void doTask(CommonTaskEntity commonTaskEntity) {try {// 1. 更新任务状态为执行中commonTaskEntity.setStatus(TaskStatusEnum.RUNNING.getValue());commonTaskMapper.update(commonTaskEntity);// 2. 获取业务类型和请求参数ExcelBizTypeEnum excelBizTypeEnum = getExcelBizTypeEnum(commonTaskEntity.getBizType());String requestParam = commonTaskEntity.getRequestParam();Object toBean = JSONUtil.toBean(requestParam, aClass);// 3. 获取对应的Service并执行导出String serviceName = this.getServiceName(requestEntity);BaseService baseService = (BaseService) SpringBeanUtil.getBean(serviceName);String fileName = getFileName(excelBizTypeEnum.getDesc());String fileUrl = baseService.export(toBean, fileName, this.getEntityName(requestEntity));// 4. 更新任务状态为成功commonTaskEntity.setFileUrl(fileUrl);commonTaskEntity.setStatus(TaskStatusEnum.SUCCESS.getValue());} catch (Exception e) {// 5. 处理失败情况handleTaskFailure(commonTaskEntity, e);} finally {// 6. 更新任务记录并发送通知commonTaskMapper.update(commonTaskEntity);sendNotifyMessage(commonTaskEntity);}}
}

处理流程

  • 状态管理:完整的任务状态流转(等待→执行中→成功/失败)
  • 异常处理:完善的异常捕获和失败重试机制
  • 动态调用:通过反射动态获取Service实例
  • 通知机制:任务完成后自动发送通知

5. 消息通知机制

@RocketMQMessageListener(topic = "${mall.mgt.excelExportTopic:EXCEL_EXPORT_TOPIC}",consumerGroup = "${mall.mgt.excelExportGroup:EXCEL_EXPORT_GROUP}"
)
@Component
public class ExcelExportConsumer implements RocketMQListener<MessageExt> {@Overridepublic void onMessage(MessageExt message) {String content = new String(message.getBody());CommonNotifyEntity commonNotifyEntity = JSONUtil.toBean(content, CommonNotifyEntity.class);pushNotify(commonNotifyEntity);}private void pushNotify(CommonNotifyEntity commonNotifyEntity) {// 通过WebSocket推送通知WebSocketServer.sendMessage(commonNotifyEntity);// 更新通知状态commonNotifyEntity.setIsPush(1);commonNotifyMapper.update(commonNotifyEntity);}
}

通知特色

  • 异步解耦:通过消息队列实现系统解耦
  • 实时推送:WebSocket确保用户及时收到通知
  • 可靠性保证:消息队列确保通知的可靠传递

技术架构亮点

1. 策略模式 + 工厂模式

public class AsyncTaskStrategyContextFactory {private static Map<Integer, IAsyncTask> asyncTaskMap;public IAsyncTask getStrategy(Integer taskType) {return asyncTaskMap.get(taskType);}
}

设计优势

  • 扩展性强:新增任务类型只需实现IAsyncTask接口
  • 维护性好:每种任务类型独立实现,互不影响
  • 配置灵活:通过工厂模式统一管理任务策略

2. 注解驱动编程

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExcelExport {ExcelBizTypeEnum value();
}

编程范式

  • 声明式编程:通过注解声明功能,而非命令式实现
  • 元数据驱动:注解携带的元数据驱动系统行为
  • 代码简洁:业务代码保持简洁,关注点分离

3. 异步任务状态机

66b3344f-aa5e-4607-9e0d-6389c5797a7c (1)

状态管理

  • 状态流转:清晰的状态转换逻辑
  • 重试机制:失败任务自动重试,提高成功率
  • 状态持久化:任务状态持久化到数据库

4. 分页大数据处理

private String doExport(V v, String fileName, String clazzName) {RequestConditionEntity conditionEntity = (RequestConditionEntity) v;// 计算分页参数int totalCount = getBaseMapper().searchCount(conditionEntity);int sheetCount = totalCount % sheetDataSize == 0 ? totalCount / sheetDataSize : totalCount / sheetDataSize + 1;// 创建ExcelWriterExcelWriter excelWriter = EasyExcel.write(file).build();// 分页处理数据for (int sheetIndex = 1; sheetIndex <= sheetCount; sheetIndex++) {List<K> dataEntities = getBaseMapper().searchByCondition(conditionEntity);// 写入数据到SheetWriteSheet writeSheet = EasyExcel.writerSheet("Sheet" + sheetIndex).head(Class.forName(clazzName)).build();excelWriter.write(dataEntities, writeSheet);conditionEntity.setPageNo(conditionEntity.getPageNo() + 1);}excelWriter.finish();return uploadToOSS(file);
}

处理策略

  • 内存优化:分页查询避免大量数据加载到内存
  • 流式处理:使用EasyExcel的流式API
  • 多Sheet支持:大数据自动分割到多个Sheet
  • 进度可控:分页处理便于监控和中断

技术优势

1. 用户体验优势

  • 即时响应:用户请求后立即返回,无需等待
  • 实时通知:通过WebSocket实时推送导出结果
  • 进度可见:用户可以实时查看导出进度
  • 错误友好:导出失败时提供详细的错误信息

2. 系统性能优势

  • 高并发:异步处理支持高并发导出请求
  • 资源优化:分页处理避免内存溢出
  • 负载均衡:任务队列支持负载均衡
  • 可扩展性:支持水平扩展和垂直扩展

3. 开发维护优势

  • 代码简洁:注解驱动,业务代码简洁
  • 易于扩展:新增业务类型只需添加注解
  • 统一管理:所有导出任务统一管理和监控
  • 错误处理:完善的异常处理和重试机制

4. 运维管理优势

  • 任务监控:完整的任务执行监控
  • 状态管理:清晰的任务状态流转
  • 日志记录:详细的操作日志记录
  • 告警机制:完善的异常告警机制

总结

苏三商城的Excel异步导出机制是一个设计精良、功能完善的企业级解决方案。

它通过以下技术手段实现了高效、稳定、可扩展的异步导出功能:

核心技术栈

  • 注解驱动@ExcelExport注解实现声明式编程
  • AOP切面CommonTaskAspect实现横切关注点分离
  • 策略模式AsyncTaskStrategyContextFactory实现任务策略管理
  • 定时调度:Quartz实现任务定时调度
  • 消息队列:RocketMQ实现异步通知
  • 实时通信:WebSocket实现实时推送
  • 文件存储:OSS实现文件云端存储

设计亮点

  1. 异步解耦:通过任务队列实现请求与处理的解耦
  2. 状态管理:完整的任务状态流转和持久化
  3. 错误处理:完善的异常处理和重试机制
  4. 性能优化:分页处理、流式写入、内存优化
  5. 扩展性强:支持业务类型、导出格式、通知方式的扩展
  6. 监控完善:完整的任务监控和告警机制

业务价值

  • 提升用户体验:异步处理避免长时间等待
  • 提高系统性能:支持大数据量导出和高并发请求
  • 降低开发成本:注解驱动减少重复代码
  • 便于运维管理:统一的任务管理和监控

这套异步导出机制不仅解决了传统同步导出的技术难题,还提供了良好的扩展性和维护性,是苏三商城项目的技术亮点之一,值得在其他项目中推广和应用。

最后说一句(求关注,别白嫖我)

如果这篇文章对您有所帮助,或者有所启发的话,帮忙关注一下我的同名公众号:苏三说技术,您的支持是我坚持写作最大的动力。

求一键三连:点赞、转发、在看。

关注公众号:【苏三说技术】,在公众号中回复:进大厂,可以免费获取我最近整理的10万字的面试宝典,好多小伙伴靠这个宝典拿到了多家大厂的offer。

更多经常内容在我的技术网站:http://www.susan.net.cn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/947962.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

化繁为简:解密国标GB28181算法算力平台EasyGBS如何以兼容性与易用性赋能安防集成

化繁为简:解密国标GB28181算法算力平台EasyGBS如何以兼容性与易用性赋能安防集成引言:国标协议的“理想”与“现实” 国标GB28181协议作为中国安防领域的通用语言,其初衷是为了解决不同品牌、不同系统之间的互联互通…

国标GB28181算法算力平台EasyGBS视频实时监控系助力实现换热站全景可视化管理

国标GB28181算法算力平台EasyGBS视频实时监控系助力实现换热站全景可视化管理一、方案背景 在城市供热体系中,换热站作为连接热源与用户的核心枢纽,其运行稳定性直接影响供热质量。面对供热规模扩大与需求升级,传统…

CSS补充

2025.10.27 打卡 不想再拖了,快速过一遍CSS结束吧。渐变,就是颜色可以渐变,要做叫美工做。阴影,可以用来加阴影,也可以设置负的值来表示一个包围文字的边框。box-shadow可以创建卡片。一些文本的高级用法,here@f…

「LG3600-随机数生成器」题解

题解记录P3600 随机数生成器 sol 期望不太方便,转计数。那么就是要求对每个值,最后结果恰为这个值的方案数。 恰好不太好求,考虑差分,转化为至多,那么就是要对每个值求答案不超过这个值的方案数。 要求所有区间区…

【每日Arxiv热文】还在为视频编辑发愁?港科大蚂蚁集团提出Ditto框架刷新SOTA!

【01 论文概述】 论文标题:ScalingInstruction-BasedVideoEditingwithaHigh-QualitySyntheticDataset 作者团队:香港科大、蚂蚁集团、浙江大学、东北大学 发布时间:2025 年 10 月 17 日 论文链接:https://arxiv.or…

计算机毕业设计springboot音乐畅听系统 基于Spring Boot框架的智能音乐播放系统编写 Spring Boot驱动的音乐在线欣赏平台构建

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

vue2 封装组件使用 v-mode【el-radio,el-input】

vue2 封装组件使用 v-mode【el-radio,el-input】v-model 在组件上使用,只能更改一个值。 sycn [singk] 1、在组件上使用 v-model ,父组件 v-model ,子组件接收value , $emit(value,xxxx)2、sync [singk]. 父组件 …

MathType7下载包安装教程2025最新下载+安装+汉化激活(附安装包,超详细)

目录前言一、MathType7 下载二、MathType7 软件介绍三、MathType7 安装 + 汉化激活全步骤(附细节提示) 前言 本文是 2025 年最新 MathType7 安装全流程教程,从MathType7 下载、安装到汉化激活、Word 配置都讲透,还…

P11993 [JOIST 2025] 迁移计划 题解

Description JOI 王国由编号从 \(1\) 到 \(N\) 的 \(N\) 个城市组成。这些城市通过 \(N − 1\) 条单向道路连接。具体来说,对于每个 \(i = 2, 3, \ldots, N\),存在一条从城市 \(i\) 通向城市 \(P_i\) 的道路。此处保…

人工智能十大数学知识-线性代数 - 何苦

人工智能十大数学知识-线性代数人工智能中的线性代数核心知识(Linear Algebra for AI)- 线性代数 1. 向量(Vector)n维空间中的有向线段,是AI数据的“原子单元”,用于表示单个样本的特征(如“身高175cm、体重60k…

2025年土地报批技术服务品牌

文章摘要 随着国家基础设施建设加速,土地报批技术服务行业迎来快速发展期。2025年土地报批技术服务市场将更加专业化、规范化,优质服务商在技术实力、服务效率和资源整合方面优势明显。本文基于行业调研数据,为您提…

2025年土地报批技术服务品牌Top10排行榜

摘要 土地报批技术服务行业随着国家基础设施建设和国土空间规划政策的深入推进,市场需求持续增长,选择可靠的服务商成为项目成功的关键。本文基于2025年市场数据、用户口碑和行业专家评价,综合整理了土地报批技术服…

2025 圆木/方木/原木多片锯设备推荐榜:河北普悦机械源头厂家凭核心技术登顶,4家优质企业各展优势

一、推荐榜背景:多片锯成行业升级刚需 2025 年,建材加工、家具制造、木材加工等领域加速产能升级,多片锯因 “高效切割、精准分料” 的核心优势,成为降低生产能耗、提升加工效率的关键设备。本次推荐榜基于设备切割…

研发排查问题的利器:一款方法调用栈跟踪工具

导语 本文从日常值班问题排查痛点出发,分析方法复用的调用链路和上下文业务逻辑,通过思考分析,借助栈帧开发了一个方法调用栈的链式跟踪工具,便于展示一次请求的方法串行调用链,有助于快速定位代码来源和流量入口…

2025年多功能综合杆厂家排名前十推荐

摘要 多功能综合杆作为智能城市建设的核心基础设施,近年来行业发展迅速,集成照明、监控、通信、环境监测等多种功能,提升城市管理效率和市民生活品质。据行业报告显示,全球智能杆市场预计到2025年将达到150亿美元,…

PlantUML-EBNF语法学习

背景 一图胜千言。有时候用图表表达意图比较直观、容易理解。但是用一般画图工具比较麻烦,也不容易修改,所以用文本描述设计意图,然后自动呈现图表就是一种理想的方案。 本文用EBNF语法图描述了语法图的语法。 参考…

2025年度在线网站客服系统综合排行榜正式发布

在信息爆炸的今天,客户耐心正以秒计算。您的网站访客可能只因一个无人应答的咨询窗口便悄然离去。一个得力的在线客服系统,早已不再是简单的“沟通工具”,而是企业挽留潜在客户、提升服务体验、最终实现业绩转化的战…

JDD Oxygen智能零售论坛 | 《大模型时代的广告营销变革与实践》

核心观点 1. 通用大模型想解决营销领域问题需向垂类模型转型。 “全才”通用大模型难覆盖广告营销全流程,需升级为“懂营销”的垂直模型,实现从“知道”到“落地执行”的三维跨越。 2. 广告智能体破解传统投放门槛高…

常用Web 实时通信技术:原理+选型,一篇通关

在 Web 开发中,实时通信技术的核心目标是实现客户端(Browser)与服务器之间低延迟、双向 / 单向的动态数据交互,而非传统 HTTP 的 “请求 - 响应” 模式。以下是 Web 端最常用的实时通信技术,从概念、原理特点、适…

ERP和CRM、SRM、MES之间的关系,怎么理解?

我的一个创业的朋友最近来问我,ERP、CRM、SRM和MES这四个系统到底该如何配合?这是很多公司在推进数字化转型时,都会遇到一个问题,我们公司也不例外。 虽然它们各自有不同的职能,但往往会让人搞不清楚。有时候,企…