客户甩来1000条Excel?3行代码自动入库!EasyExcel 导入真香
大家好,我是“不想打工的码农”。
以前一听到“Excel导入”,我就头大:
“要处理空行、格式错乱、重复数据、还要校验字段……稍不注意服务器就 OOM(内存溢出)!”
但自从用了 EasyExcel 的读取功能,我发现:只要设计好监听器,万级数据也能稳稳入库,内存占用几乎不变!
今天,我就手把手教你,如何用 Spring Boot + EasyExcel,实现一个安全、高效、带校验的学生信息导入功能。
一、为什么不能直接用 POI 读 Excel?
- 内存爆炸:POI 会把整个 Excel 文件加载到内存,1万行数据轻松吃掉几个G内存。
- 代码复杂:要自己遍历行、列,处理各种单元格类型(文本、数字、日期)。
- 容错差:遇到格式错误,整个导入就挂了。
而 EasyExcel 采用“事件驱动”模型——一行一行读,读完就丢,绝不囤货,内存占用恒定!
二、实战:4步实现安全导入
第1步:前端加“导入”按钮和文件选择
在 Vue 学生管理页面顶部,加一个导入区域:
<el-upload action="/student/import" :show-file-list="false" :on-success="handleImportSuccess" :headers="{ 'Content-Type': 'multipart/form-data' }"> <el-button type="primary">导入Excel</el-button></el-upload><script setup>const handleImportSuccess = (res) => { ElMessage.success(`成功导入 ${res.data} 条数据!`); fetchStudents(); // 刷新列表}</script>第2步:定义 Excel 数据模型(复用导出VO)
还记得上期我们写的 StudentExcelVO.java 吗?直接复用它!
public class StudentExcelVO { @ExcelProperty("学号") private Integer id; @ExcelProperty("姓名") private String name; @ExcelProperty("年龄") private Integer age; @ExcelProperty("邮箱") private String email; // getter/setter}✅ 字段名和表头必须严格对应!
第3步:写数据监听器(核心!5行业务逻辑)
新建 StudentDataListener.java:
@Componentpublic class StudentDataListener extends AnalysisEventListener<StudentExcelVO> { @Autowired private StudentService studentService; // 注入你的业务Service // 每读一行数据,就会调用一次 @Override public void invoke(StudentExcelVO data, AnalysisContext context) { // 简单校验 if (data.getName() == null || data.getAge() == null) { throw new RuntimeException("姓名或年龄不能为空"); } // 调用Service保存(内部可做去重、转换等) studentService.saveStudentFromExcel(data); } // 全部读完后调用 @Override public void doAfterAllAnalysed(AnalysisContext context) { // 可以在这里发通知、清理资源等 }}第4步:写导入接口(核心!3行代码)
在 StudentController 中新增:
@PostMapping("/import")public ResponseEntity<Map<String, Object>> importStudents(MultipartFile file) throws IOException { Map<String, Object> result = new HashMap<>(); // ✅ 核心就这三行! StudentDataListener listener = new StudentDataListener(); EasyExcel.read(file.getInputStream(), StudentExcelVO.class, listener).sheet().doRead(); result.put("data", "导入完成"); // 实际可返回成功数量 return ResponseEntity.ok(result);}看!真正的导入逻辑就一行!
EasyExcel 自动按行读取,每行触发 invoke 方法,你只管处理业务!
三、避坑指南:导入功能的3大生死线
- 防止内存溢出(OOM)
EasyExcel 默认就是流式读取,不会OOM。但如果你在 invoke 里把所有数据存到 List 再批量插入,还是会崩!
✅ 正确做法:在 invoke 里立即处理并清空,或者每1000条批量插入一次。 - 处理重复数据
在 studentService.saveStudentFromExcel() 里,先查数据库是否已存在(比如按邮箱),避免重复插入。 - 友好错误提示
如果某一行格式错误,EasyExcel 会抛异常。你可以在 Controller 里 catch,返回具体哪一行错了,而不是“导入失败”。

四、进阶技巧:让导入更智能
- 模板下载:提供一个标准 Excel 模板(带表头),让用户照着填。
- 预览模式:先上传文件,展示前10行数据让用户确认,再点“确认导入”。
- 异步导入:大文件导入很耗时,可改为“上传 → 后台异步处理 → 完成后通知”,避免 HTTP 超时。
五、结语:你的系统,已打通“数据闭环”
现在,你的学生管理系统实现了完整的数据流转:
Excel导入 → ️ 在线管理 → Excel导出
客户再也不用手动录入,也不用担心数据丢失。这种端到端的数据解决方案,正是企业客户愿意付费的核心价值!
我是“不想打工的码农”,一个正在用“小功能”解决大问题的普通人。下期见!
#EasyExcel#Excel导入#SpringBoot##Java开发##程序员副业##数据导入##代码教程##不想打工的码农#程序员##职场##本轮寒潮与08年冰灾范围相似#
文章版权声明:除非注明,否则均为边学边练网络文章,版权归原作者所有