java 如何使用easyExcel 根据文件流 解析excel ? 写出详细例子
时间: 2025-07-19 14:34:23 浏览: 7
<think>我们使用EasyExcel读取Excel文件流,并给出一个详细的示例代码。我们将包括以下步骤:
1. 添加Maven依赖
2. 定义数据模型(如果需要将Excel数据映射到对象)
3. 编写读取Excel的代码,使用文件流(InputStream)
4. 使用监听器逐行处理数据
5. 关闭资源(使用try-with-resources自动关闭流)
注意:EasyExcel在读取时,默认会关闭传入的InputStream,但为了安全,我们通常使用try-with-resources来确保流被关闭。
详细代码示例如下:</think>### Java EasyExcel 文件流解析 Excel 详细示例代码
以下是使用 EasyExcel 通过文件流解析 Excel 的完整实现方案(包含数据模型绑定和异常处理):
#### 1. Maven 依赖配置
```xml
<dependencies>
<!-- EasyExcel 核心依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.3.2</version>
</dependency>
<!-- Lombok 简化代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
</dependencies>
```
#### 2. 定义数据模型类
```java
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
@Data // Lombok自动生成getter/setter
public class Employee {
@ExcelProperty("员工ID") // 对应Excel列名
private Integer id;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("部门")
private String department;
@ExcelProperty("薪资")
private Double salary;
}
```
#### 3. 实现数据监听器
```java
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import java.util.ArrayList;
import java.util.List;
public class EmployeeDataListener implements ReadListener<Employee> {
// 存储解析结果
private final List<Employee> dataList = new ArrayList<>();
// 每解析一行数据触发
@Override
public void invoke(Employee employee, AnalysisContext context) {
System.out.println("解析到数据: " + employee);
dataList.add(employee);
}
// 所有数据解析完成后触发
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("Excel解析完成,共解析: " + dataList.size() + " 条数据");
}
// 获取解析结果
public List<Employee> getDataList() {
return new ArrayList<>(dataList);
}
}
```
#### 4. 核心解析代码
```java
import com.alibaba.excel.EasyExcel;
import java.io.InputStream;
public class ExcelParser {
public List<Employee> parseExcel(InputStream inputStream) {
// 创建数据监听器
EmployeeDataListener listener = new EmployeeDataListener();
try {
// 核心解析代码(一行搞定)
EasyExcel.read(inputStream)
.head(Employee.class) // 绑定数据模型
.sheet() // 读取第一个sheet
.registerReadListener(listener) // 注册监听器
.doRead(); // 执行读取
} finally {
// 确保关闭流
closeStream(inputStream);
}
return listener.getDataList();
}
private void closeStream(InputStream is) {
try {
if (is != null) is.close();
} catch (Exception e) {
System.err.println("关闭流异常: " + e.getMessage());
}
}
// 示例:从类路径读取文件
public static void main(String[] args) {
InputStream is = ExcelParser.class
.getClassLoader()
.getResourceAsStream("employees.xlsx");
List<Employee> employees = new ExcelParser().parseExcel(is);
System.out.println("解析结果: " + employees);
}
}
```
#### 5. Spring Boot 控制器集成示例
```java
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
@RestController
@RequestMapping("/excel")
public class ExcelImportController {
@PostMapping("/import")
public String importExcel(@RequestParam("file") MultipartFile file) {
try (InputStream is = file.getInputStream()) {
List<Employee> employees = new ExcelParser().parseExcel(is);
return "导入成功,共处理: " + employees.size() + " 条记录";
} catch (Exception e) {
return "导入失败: " + e.getMessage();
}
}
}
```
### 关键特性说明
1. **流式处理机制**:
- 使用`InputStream`作为输入源,支持文件/网络流
- 逐行解析,内存占用恒定(约 50MB/100万行)[^1]
- 自动识别 Excel 格式(.xlsx/.xls)
2. **数据绑定优势**:
```java
@ExcelProperty("员工ID")
private Integer id;
```
- 通过注解实现列名到字段的映射
- 支持数据类型自动转换(字符串→数字/日期等)
3. **异常处理机制**:
```java
// 自定义异常处理器
.registerReadListener(new ReadListener<Employee>() {
@Override
public void onException(Exception e, AnalysisContext context) {
// 处理解析异常
}
})
```
4. **性能优化参数**:
```java
.readCache(new MapCache()) // 自定义缓存
.headRowNumber(0) // 无表头模式
.sheet(1) // 读取第二个sheet
```
### 实际应用场景
1. **数据导入**:
```java
// 批量插入数据库
employees.forEach(employeeRepository::save);
```
2. **数据校验**:
```java
@Override
public void invoke(Employee data, AnalysisContext context) {
if (data.getSalary() < 0) {
throw new RuntimeException("薪资不能为负数");
}
}
```
3. **大文件分片处理**:
```java
.sheet(rowIndex -> {
// 每处理1000行保存一次
if (rowIndex % 1000 == 0) saveBatch(dataList);
})
```
### 注意事项
1. **流关闭策略**:
- 使用 `try-with-resources` 确保流关闭
- Spring 的 `MultipartFile` 需手动获取流
2. **表头匹配规则**:
- 默认按注解顺序匹配列
- 添加 `@ExcelProperty(index = 0)` 按索引匹配
3. **空值处理**:
```java
@ExcelProperty("备注")
@ColumnWidth(20)
private String remark = ""; // 默认值避免null
```
4. **日期格式化**:
```java
@DateTimeFormat("yyyy-MM-dd")
private Date hireDate;
```
[^1]: EasyExcel 通过流式解析模型实现低内存占用,特别适合处理大数据量 Excel 文件
[^2]: 数据监听器模式解耦了解析逻辑和业务处理,符合单一职责原则
[^3]: 模型绑定机制大幅简化了数据转换代码,相比传统 POI 减少 70% 的样板代码
阅读全文
相关推荐


















