Master Efficient Excel Imports in Java with EasyExcel and Spring Boot
This article explains how Java backend developers can replace memory‑heavy Apache POI with EasyExcel for fast, low‑memory Excel imports, covering basic reading, custom converters for gender and dates, and multiple Spring Boot integration patterns including controllers, listeners, constructor injection and lambda‑based approaches.
Java backend developers often face memory‑intensive Excel imports when using Apache POI, which loads the entire file into memory. EasyExcel solves this problem by reading rows sequentially, reducing memory usage from hundreds of megabytes to just a few megabytes even for large files.
Simple Read
Assuming an Excel sheet with name and age columns, define a User entity:
@Data
public class User {
/** Name */
@ExcelProperty(index = 0)
private String name;
/** Age */
@ExcelProperty(index = 1)
private Integer age;
}The @ExcelProperty annotation can use index (column order) or name (header text). The official documentation recommends not mixing both:
Do not use index and name simultaneously; choose one method per field.
If the Excel template columns are fixed, use index for stability.
If column order changes frequently, use name to avoid updating indices.
Custom Converter
To map gender values "男"/"女" to numeric codes, create a converter:
public class GenderConverter implements Converter<Integer> {
public static final String MALE = "男";
public static final String FEMALE = "女";
@Override
public Class supportJavaTypeKey() { return Integer.class; }
@Override
public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; }
@Override
public Integer convertToJavaData(CellData cellData, ExcelContentProperty prop, GlobalConfiguration cfg) {
String value = cellData.getStringValue();
return MALE.equals(value) ? 1 : 2;
}
@Override
public CellData convertToExcelData(Integer value, ExcelContentProperty prop, GlobalConfiguration cfg) {
return null; // not needed for import
}
}Apply it to the entity:
/** Gender: 1‑Male, 2‑Female */
@ExcelProperty(index = 2, converter = GenderConverter.class)
private Integer gender;Date Conversion
For a birth date column, use @DateTimeFormat to specify the desired pattern:
@ExcelProperty(index = 3)
@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
private String birth;Web Reading with Spring Boot
Expose a REST endpoint that reads an uploaded Excel file:
@RestController
@RequestMapping("/users")
@Slf4j
public class UserController {
@PostMapping("/upload")
public String upload(MultipartFile file) throws IOException {
EasyExcel.read(file.getInputStream(), User.class, new UserExcelListener())
.sheet().doRead();
return "success";
}
}Several listener integration patterns are demonstrated:
Anonymous Inner Class
EasyExcel.read(file.getInputStream(), User.class, new AnalysisEventListener<User>() {
private static final int BATCH_COUNT = 2;
List<User> list = new ArrayList<>();
@Override
public void invoke(User user, AnalysisContext ctx) {
log.info("Parsed: {}", JSON.toJSONString(user));
list.add(user);
if (list.size() >= BATCH_COUNT) { saveData(); list.clear(); }
}
@Override
public void doAfterAllAnalysed(AnalysisContext ctx) { saveData(); }
private void saveData() { iUser.saveData(list); }
}).sheet().doRead();Constructor Injection
public class UserExcelListener extends AnalysisEventListener<User> {
private final IUser iUser;
public UserExcelListener(IUser iUser) { this.iUser = iUser; }
// invoke / doAfterAllAnalysed similar to above, calling iUser.saveData(...)
}
// Controller usage
EasyExcel.read(file.getInputStream(), User.class, new UserExcelListener(iUser))
.sheet().doRead();Lambda‑Based Listener
Wrap the listener creation in a utility that accepts a Consumer<List<User>>:
public static <T> AnalysisEventListener<T> getListener(Consumer<List<T>> consumer) {
return new AnalysisEventListener<T>() {
private static final int BATCH_COUNT = 1000;
List<T> buffer = new ArrayList<>();
@Override
public void invoke(T data, AnalysisContext ctx) {
buffer.add(data);
if (buffer.size() >= BATCH_COUNT) { consumer.accept(buffer); buffer.clear(); }
}
@Override
public void doAfterAllAnalysed(AnalysisContext ctx) { consumer.accept(buffer); }
};
}
// Controller usage
EasyExcel.read(file.getInputStream(), User.class,
ExcelDemoUtils.getListener(list -> iUser.saveData(list)))
.sheet().doRead();Summary
EasyExcel provides a memory‑efficient way to import Excel data in Java, supporting simple row mapping, custom converters for complex fields, and seamless integration with Spring Boot controllers through various listener patterns. By leveraging Java 8 functional interfaces, developers can keep controller code clean while maintaining flexible, reusable data‑processing logic.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
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.
