使用 Spring Boot 实现 Excel 导出 + 邮件异步发送功能,解决接口阻塞问题

一、背景介绍
最近我在开发一个跑团管理系统的数据导出功能,需求是将用户查询的成员信息、跑量统计等数据导出为 Excel 文件,并通过邮件自动发送至指定邮箱,而非让用户手动下载文件。
虽然功能逻辑看起来不复杂,但在实际开发过程中遇到了一些关键性问题:
导出 Excel 后发送邮件耗时较长,导致接口响应延迟;
QQ 邮箱 SMTP 校验严格,出现 550 The "From" header is missing or invalid 异常;
接口体验差,用户点击后需要等待很久才能收到响应。
于是我对整个流程进行了分析与重构,最终实现了高性能、高可用的数据导出 + 邮件发送功能。

二、功能实现流程概览
用户发起请求,选择导出类型(成员列表 / 跑量统计等);
系统调用服务层获取数据;
使用 Apache POI 构建 Excel 文件并写入内存流(ByteArrayOutputStream);
将生成的 Excel 字节数组作为附件,使用 JavaMailSender 发送邮件;
返回接口响应,提示邮件已发送成功(实则后台异步执行);

三、遇到的问题与解决方案
问题一:Excel 导出时报错 sheetName must not be null
原因:
Apache POI 要求每个 Sheet 必须有名称,否则抛出异常。
解决方案:
在创建 ExcelUtil 实例后显式设置 sheetName,例如:

ExcelUtil<PersonalRunningGroupExportVO> util = new ExcelUtil<>(PersonalRunningGroupExportVO.class);
util.setSheetName("跑团数据");

问题二:QQ 邮箱发送失败,报错 550 The "From" header is missing or invalid
原因:
QQ 邮箱对发件人地址校验非常严格,要求 MAIL FROM 地址必须与登录账号一致,否则拒绝发送。
解决方案:
在邮件构建器中显式设置发件人地址:

MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom("your-qq@qq.com"); // 必须与 spring.mail.username 一致

同时确保配置文件中使用的是授权码,而非登录密码:

spring:
mail:
host: smtp.qq.com
port: 587
username: your-qq@qq.com
password: 授权码
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true

问题三:发送邮件过程很慢,影响接口响应时间
原因:
邮件发送属于 I/O 操作,受网络、服务器限制,同步执行会阻塞主线程,影响用户体验。
解决方案:
引入 Spring 的异步任务支持 @Async,将邮件发送操作放入子线程处理。
步骤如下:
1.在启动类上添加 @EnableAsync
2.创建邮件服务类 EmailService,并在方法上添加 @Async
3.Controller 中调用异步方法发送邮件,立即返回结果

示例代码:

@Async
public void sendExcelEmailAsync(String to, byte[] data, String fileName) {
try {
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom("your-qq@qq.com");
helper.setTo(to);
helper.setSubject("导出的跑团数据");
helper.setText("请查收附件中的跑团数据。");
helper.addAttachment(fileName + ".xlsx", new ByteArrayResource(data));
javaMailSender.send(message);
} catch (Exception e) {
log.error("邮件发送失败:{}", e.getMessage());
}
}

四、优化效果
优化前
接口需等待邮件发送完成才返回
用户需等待 3~5 秒甚至超时
多次请求客易造成线程阻塞
QQ 邮箱频繁报错无法发送
优化后
接口立即返回,邮件后台异步发送
接口响应时间缩短至 300ms 内
支持并发发送,提升吞吐能力
设置 From 后成功发送,兼客性强

五、总结
这次开发让我深刻体会到:
邮件发送应尽量避免阻塞主线程,建议统一走异步化处理;
Spring Boot 提供了强大的异步支持,只需简单配置即可使用;
QQ 邮箱对发件人地址校验严格,务必保证 From 和 Username 一致;
使用 ByteArrayOutputStream 替代临时文件,更安全高效;
合理封装 ExcelUtil 工具类,提高复用性和可维护性。

六、完整功能点清单(便于读者参考)
功能模块                                                       技术点
数据导出                                                       Apache POl
Excel写入内存            ByteArrayOutputStream
邮件发送              JavaMailSender/Jakarta Mail
异步处理            @Async + ThreadPoolTaskExecutor
邮箱验证              SMTP from 一致性校验
接口优化              非阻塞响应设计
邮箱类型             QQ/Gmail/网易等通用适配

七、结语
如果你也在做类似的数据导出 + 邮件通知功能,希望这篇文章能帮你少踩坑,快速上线稳定版本。如有疑问欢迎留言交流,也欢迎你分享你的优化思路!

将数据导出 Excel 并异步发送到指定邮箱:一次性能优化实战的更多相关文章

  1. C#/Net定时导出Excel并定时发送到邮箱

    一.定时导出Excel并定时发送到邮箱   首先我们先分析一下该功能有多少个小的任务点:1.Windows计划服务 2.定时导出Excel定指定路径 3.定时发送邮件包含附件   接下来我们一个个解决 ...

  2. 百度地图里面搜索到的公司商家电话导出表格?怎样将把百度地图里面搜索到的公司 电话 地址 等数据导出excel里?

    好多人在问:如何将百度地图里面搜索到的公司商家电话导出表格?怎样将把百度地图里面搜索到的公司 电话 地址 等数据导出excel里? 现在,很多人都在网络上找商家,联系业务. 百度地图里有很多的商家联系 ...

  3. 【asp.net】将GridView数据导出Excel

    概要: 中午睡了一会,醒来的时候看到老师叫我去办公室,需求是这样的,把excel表中的每个同学,判断图片目录中是否有对应的照片(图片的名字用的学号或身份证号码) 没有对应图片的学生记录,存入自己的数据 ...

  4. Java使用POI实现数据导出excel报表

    Java使用POI实现数据导出excel报表 在上篇文章中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式.不仅 ...

  5. JavaScript 上万条数据 导出Excel文件(改装版)

    最近项目要js实现将数据导出excel文件,网上很多插件实现~~那个开心呀,谁知道后面数据量达到上万条时出问题:浏览器不仅卡死,导出的excel文件一直提示网络失败.... debug调试发现var  ...

  6. JavaScript 上万条数据 导出Excel文件 页面卡死

    最近项目要js实现将数据导出excel文件,网上很多插件实现~~那个开心呀,谁知道后面数据量达到上万条时出问题:浏览器不仅卡死,导出的excel文件一直提示网络失败.... debug调试发现var  ...

  7. 将页面中表格数据导出excel格式的文件(vue)

    近期由于项目需要,需要将页面中的表格数据导出excel格式的文件,折腾了许久,在网上各种百度,虽然资料不少,但是大都不全,踩了许多坑,总算是皇天不负有心人,最后圆满解决了. 1.安装相关依赖(npm安 ...

  8. iPhone上将短信内容发送到指定邮箱的方法

    iPhone上将短信内容发送到指定邮箱的方法 迄今为止,移动应用安全基本聚焦在以下几个方面,一是移动设备管理BYOD(bring your own device),二是移动恶意软件分析,三是移动设备用 ...

  9. 屏幕监视专家 v1.0 定时录制屏幕动画发送到指定邮箱

    ScreenWatcher v1.0功能:定时录制屏幕动画发送到指定邮箱,录制的动画为gif,可指定录制多长时间.指定几点直接开始录制,完全后台运行.作者:Bluefish 下载链接: http:// ...

  10. PHP自学4——通过mail函数将feedback界面用户填写表单信息发送至指定邮箱

    这一讲的内容依旧简单(谁叫PO主水平菜,依旧是个弱鸡ORZ),通过PHP的内置mail函数将一个反馈界面的信息发送到指定邮箱.在Windows平台不能直接需要使用该函数,需要下载一个sendmail并 ...

随机推荐

  1. 『Python底层原理』--CPython的变量实现机制

    在Python中,变量的使用看起来非常简单,例如 a = 10,s = "hello"等等. 然而,这种简单的赋值操作背后,CPython其实做了很多复杂的工作. 本文将通过一些简 ...

  2. .NET Core 托管堆内存泄露/CPU异常的常见思路

    常见的思路 内存泄露 托管内存暴涨大多数原因都是因为对象被GC Root(stack,gchandle,finalizequeue)持有,所以一直无法释放,所以观察的重点都在对象的可疑GC Root ...

  3. Typecho防黑安全加固-修改后台路径

    删除安装文件 成功安装后删除install.php文件.install/文件夹. 修改后台地址 把admin修改为黑客猜不到的名字,例如pipixia,防止黑客穷举密码. 修改admin文件夹名称 修 ...

  4. FastAPI极速入门:15分钟搭建你的首个智能API(附自动文档生成)🚀

    title: FastAPI极速入门:15分钟搭建你的首个智能API(附自动文档生成) date: 2025/3/1 updated: 2025/3/1 author: cmdragon excerp ...

  5. vue3用vite新建项目

    1. npm init vue@latest vue3-project 调用create-app创建, 指定了目录是vue3-projece,但是,紧接着有一堆配置要询问. 2. npm create ...

  6. Oracle操作审计

    因为信安的要求,要对Oracle加审计.看了一下,原来是有开的,类型为DB: SQL> show parameter audit; NAME TYPE VALUE --------------- ...

  7. selenium自动化测试-获取黄金实时价格

    最近黄金比较火爆,想要获取黄金实时价格,方便后续监控预警价格,一般实时刷新的网页数据都是动态加载的,需要用到selenium自动化测试获取动态页面数据. 昨天学会了获取动态网页小说内容,同理也可以获取 ...

  8. 使用 bc4 解决 git 合并冲突问题

    博客地址:https://www.cnblogs.com/zylyehuo/ STEP1:安装 beyond compare 安装地址: https://www.scootersoftware.com ...

  9. 05 过拟合(over-fitting)与正则化(regularization)

    1. 什么是Overfitting 我们希望神经网络模型能够找到数据集中的一般规律,从而帮助我们预测未知数据.这个过程是通过不断地迭代优化损失函数(也就是预测值和实际值的误差)而实现的.然而随着误差进 ...

  10. Linux性能分析-平均负载

    平均负载的理解 一般系统变慢时,我们会使用top或uptime命令来查看下系统的负载情况 [root@localhost shell]# uptime 13:51:08 up 5 days, 21:5 ...