Using EasyExcel Spring Boot Starter for Excel Import, Export and Validation
This article introduces the EasyExcel‑Spring‑Boot‑Starter project, explains the limitations of POI and EasyExcel, shows how to integrate it into a Spring Boot application with Maven dependencies, demonstrates Excel import and export APIs, and provides comprehensive validation and error‑handling mechanisms for robust backend development.
Excel import and export are common in Java projects, traditionally implemented with Apache POI, which consumes large memory and can cause OOM or frequent full GC under high concurrency; Alibaba therefore open‑sourced EasyExcel to reduce memory usage and simplify the API via annotations.
Despite its advantages, EasyExcel still has drawbacks: extensive boilerplate code similar to JDBC when many import/export features are needed, lack of built‑in validation for imported data, and no native Spring Boot integration.
To address these issues, a custom easyexcel-spring-boot-starter was created, encapsulating EasyExcel functionality, providing Spring MVC argument resolvers, and adding validation support, thereby lowering the entry barrier for simple import/export scenarios.
First, add the Maven dependency (the artifact is not yet published to a central repository): <dependency> <groupId>com.zzuhkp</groupId> <artifactId>easyexcel-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
Define a model class that maps Excel columns to fields using @ExcelProperty : @Data public class DemoData { @ExcelProperty(index = 0) private Integer integer; @ExcelProperty(index = 1) private String string; @ExcelProperty(index = 2) private Date date; }
Basic import can be implemented with a controller method that receives a list of DemoData via the custom @ExcelParam annotation: @PostMapping("/list/obj") public List listObj(@ExcelParam List list) { return list; }
For advanced import, use ReadRows<T> to obtain row and column metadata: @PostMapping("/list/rows") public ReadRows readRows(@ExcelParam ReadRows readRows) { return readRows; }
Export is equally simple; annotate the controller method with @ExcelResponse and return a list of objects: @ExcelResponse @GetMapping("/list/download") public List downloadList() { return Arrays.asList(new DemoData(1, "hello", new Date()), new DemoData(2, "excel", new Date())); }
Validation is supported by adding Spring’s @Validated or @Valid to the @ExcelParam parameter, leveraging JSR‑303 Bean Validation annotations such as @NotNull on model fields.
For custom validation across all rows, implement the framework’s ExcelValidator<T> interface. Example implementation checks that the integer field is unique and records errors via ExcelValidErrors : @Component public class CustomExcelValidator implements ExcelValidator { @Override public ExcelValidErrors validate(ReadRows readRows) { ExcelValidErrors errors = new ExcelValidErrors(); Map >> group = readRows.getRows().stream() .collect(Collectors.groupingBy(item -> item.getData().getInteger())); for (Map.Entry >> entry : group.entrySet()) { if (entry.getValue().size() > 1) { for (ReadRow readRow : entry.getValue()) { errors.addError(new DefaultExcelObjectError(readRow.getRowIndex() + 1, "参数重复")); } } } return errors; } }
When validation fails, the framework throws ExcelValidException . You can handle it globally: @RestControllerAdvice public class GlobalExceptionControllerAdvice { @ExceptionHandler(ExcelValidException.class) public String handleException(ExcelValidException e) { ExcelValidErrors errors = e.getErrors(); return JSON.toJSONString(errors); } } Alternatively, capture validation results directly in a controller method by adding an ExcelValidErrors parameter after the @ExcelParam argument.
In summary, easyexcel-spring-boot-starter combines the discussed Spring techniques, provides a lightweight solution for simple Excel import/export scenarios, and is suitable for projects that can afford loading all rows into memory.
Architect's Tech Stack
Java backend, microservices, distributed systems, containerized programming, and more.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.