easyexcel读取合并表头
时间: 2025-05-22 11:01:53 浏览: 44
### 使用 EasyExcel 读取带有合并表头的 Excel 文件
当面对含有合并单元格特别是合并表头的情况时,EasyExcel 提供了几种方法来确保能够正确解析这些复杂结构的数据。以下是具体实现方案:
#### 方法一:监听器模式读取(不创建实体对象)
这种方法适用于不需要映射到特定 Java 对象场景下的简单数据提取。
1. **准备依赖**
确保项目中已引入 EasyExcel 的 Maven 或 Gradle 依赖项[^3]。
2. **编写监听器 `ImportExcelListener`**
定义一个实现了 `AnalysisEventListener<T>` 接口的类作为事件处理器,用于接收每一行的数据并处理合并单元格逻辑。
```java
public class ImportExcelListener extends AnalysisEventListener<Map<Integer, String>> {
private List<List<String>> dataList = new ArrayList<>();
@Override
public void invoke(Map<Integer, String> data, AnalysisContext context) {
// 处理每行数据,这里可以加入针对合并单元格特殊处理逻辑
List<String> rowList = new LinkedList<>(data.values());
dataList.add(rowList);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
System.out.println("所有数据解析完成");
}
public List<List<String>> getData() {
return this.dataList;
}
}
```
3. **工具类 `ImportExcelUtil` 实现读取功能**
利用上述监听器配合 EasyExcel API 进行文件读入操作。
```java
import com.alibaba.excel.EasyExcel;
public final class ImportExcelUtil {
/**
* 解析指定路径下Excel文档中的内容至集合内.
*/
public static List<List<String>> read(String filePath){
File file = new File(filePath);
ImportExcelListener listener = new ImportExcelListener();
EasyExcel.read(file, Map.class, listener).sheet().doRead();
return listener.getData();
}
}
```
4. **执行测试验证结果**
调用 `ImportExcelUtil.read()` 方法传入目标 Excel 文件路径即可开始读取过程,并通过打印输出确认最终获得的结果集是否符合预期。
---
#### 方法二:基于模型的方式读取(创建实体对象)
对于更复杂的业务需求,则推荐采用此法——即先定义好相应的 POJO 类型表示各列字段关系,再利用 EasyExcel 自动化特性简化开发流程。
1. **定义实体类 `TestModel`**
假设存在如下简单的 Excel 表单布局:
| A | B |
|--------|-------|
| HeaderA|HeaderB|
| Value1 |Value2 |
可以构建对应的 Java Bean 如下:
```java
import lombok.Data;
import com.alibaba.excel.annotation.ExcelProperty;
@Data
public class TestModel {
@ExcelProperty(index=0)
private String headerA;
@ExcelProperty(index=1)
private String headerB;
}
```
2. **自定义监听器 `UploadDataListener`**
继承自 `AnalysisEventListener<TestModel>` 并重写相应钩子函数以便于捕获转换后的实例以及应对可能出现的各种异常状况。
```java
public class UploadDataListener extends AnalysisEventListener<TestModel> {
private List<TestModel> list = Lists.newArrayList();
@Override
public void invoke(TestModel testModel, AnalysisContext analysisContext) {
if (testModel != null && StringUtils.isNotBlank(testModel.getHeaderA())) {
list.add(testModel);
} else {
log.warn("跳过空白行...");
}
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
log.info("{}条有效记录被成功加载", list.size());
}
public List<TestModel> getList(){
return Collections.unmodifiableList(list);
}
}
```
3. **辅助工具类 `ExcelAnalysisHelper`**
此处提供了一个静态工厂方法用来便捷地启动整个导入进程。
```java
import org.springframework.web.multipart.MultipartFile;
public abstract class ExcelAnalysisHelper {
protected static <T> List<T> parse(MultipartFile multipartFile,
Class<T> clazz,
AnalysisEventListener<T> eventListener) throws Exception{
try(InputStream inputStream = multipartFile.getInputStream()){
EasyExcel.read(inputStream,clazz,eventListener).sheet().doReadSync();
return ((AbstractAnalysisEventListener<?>)eventListener).getData();
}
}
}
```
4. **实际调用示例**
结合 Spring MVC 控制器层接口设计上传入口点,内部调用前述封装好的帮助程序完成核心工作流。
```java
@RestController
@RequestMapping("/api/excels")
public class ExcelController {
@PostMapping(value="/upload", consumes="multipart/form-data")
ResponseEntity<?> handleFileUpload(@RequestParam MultipartFile file){
try {
List<TestModel> result = ExcelAnalysisHelper.parse(
file, TestModel.class, new UploadDataListener());
// 返回JSON响应体给前端展示
return ResponseEntity.ok(result);
} catch(Exception e){
throw new RuntimeException(e.getMessage(),e);
}
}
}
```
这两种途径都能有效地解决 EasyExcel 在遇到合并单元格尤其是表头部分所面临的挑战;不过考虑到灵活性与可维护性的因素,在大多数情况下建议优先选用第二种面向对象的设计思路来进行编码实践。
阅读全文
相关推荐

















