JavaWeb 实现 Excel 数据导入指南
在 JavaWeb 开发中,Excel 导入是一个非常常见的需求,目前主流的实现方案主要分为两种:使用传统的 Apache POI 和使用阿里巴巴开源的 EasyExcel。
常用依赖库对比
- Apache POI:Java 处理 Office 文档的标准库,功能极其强大,但内存消耗高,在处理大数据量(万级以上)时容易出现
OutOfMemoryError。 - EasyExcel:基于 POI 的封装库,通过逐行读取而非一次性加载到内存,极大地降低了内存占用,且代码更加简洁,是目前企业级开发的首选。
使用 Alibaba EasyExcel (推荐)
EasyExcel 采用了注解驱动的方式,将 Excel 的列与 Java 实体类直接绑定。
引入依赖
在 pom.xml 中添加依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.x.x</version>
</dependency>
创建实体类
使用 @ExcelProperty 注解定义 Excel 列名与字段的对应关系。
public class UserData {
@ExcelProperty("用户名")
private String username;
@ExcelProperty("年龄")
private Integer age;
@ExcelProperty("邮箱")
private String email;
// Getter and Setter...
}
编写监听器 (Listener)
EasyExcel 通过监听器异步处理数据,避免内存溢出。
public class UserDataListener extends AnalysisEventListener<UserData> {
// 每隔 100 条数据批量插入一次数据库
private static final int BATCH_COUNT = 100;
private List<UserData> cachedDataList = new ArrayList<>();
@Override
public void invoke(UserData data, AnalysisContext context) {
cachedDataList.add(data);
if (cachedDataList.size() >= BATCH_COUNT) {
saveData();
cachedDataList.clear();
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
saveData(); // 处理最后一批数据
}
private void saveData() {
// 调用 Service 层将 cachedDataList 批量插入数据库
}
}
控制层调用
@PostMapping("/import")
public String importExcel(@RequestParam("file") MultipartFile file) throws IOException {
EasyExcel.read(file.getInputStream(), UserData.class, new UserDataListener()).sheet().doRead();
return "导入成功";
}
使用 Apache POI (传统方式)
适用于对 Excel 文件进行复杂操作(如修改格式、合并单元格)的场景。
核心实现步骤
- 获取工作簿:使用
WorkbookFactory.create(inputStream)。 - 遍历 Sheet:通过
workbook.getSheetAt(0)获取第一个工作表。 - 遍历行与列:使用双重
for循环遍历Row和Cell。 - 处理单元格类型:必须判断
CellType(String, Numeric, Boolean 等),否则会抛出异常。
核心代码片段
Workbook workbook = WorkbookFactory.create(file.getInputStream());
Sheet sheet = workbook.getSheetAt(0);
for (Row row : sheet) {
if (row.getRowNum() == 0) continue; // 跳过表头
String name = row.getCell(0).getStringCellValue();
double age = row.getCell(1).getNumericCellValue();
// 保存到数据库...
}
workbook.close();
核心实现流程总结
无论使用哪种工具,一个完整的导入流程应包含以下环节:
- 文件上传:通过
MultipartFile接收前端上传的.xls或.xlsx文件。
- 格式校验:检查文件后缀名,防止非法文件上传。
- 数据解析:将 Excel 行转换为 Java 对象。
- 数据验证:
- 非空校验:必填项是否缺失。
- 类型校验:数字列是否包含文字。
- 业务校验:例如用户账号是否已存在。
- 批量入库:严禁在循环中逐条调用
insert语句,应使用batchInsert提高性能。 - 结果反馈:告知用户导入成功了多少条,失败了多少条,以及失败的具体原因(通常导出错误日志文件)。
关键优化点
- 内存优化:大数据量必须使用 EasyExcel 或 POI 的 SXSSF 模式。
- 性能优化:使用数据库的 批量插入 (Batch Insert) 机制。
- 事务管理:根据业务需求决定是“全部成功才提交”还是“部分成功部分失败”。
- 异步处理:对于超大型文件,建议采用 异步处理(提交任务 $rightarrow$ 后台解析 $rightarrow$ 通知用户结果)。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/491341.html



