轻量级、注解驱动的 Excel 导入/导出映射器(Java JDK 17+)。
spring-excel-mapper 提供注解驱动的 Excel Workbook/Sheet 与 Java POJO 之间的映射,以及将对象导出到 Excel 模板(保留样式)的工具。
核心功能:
@ExcelSheet、@ExcelRow、@ExcelSection、@ExcelColumn 用于模型映射ExcelMapper 提供 parseWorkbook 和 parseWorkbookWithResult(返回 ImportResult<T>)ExcelExporter 辅助填充模板行/区段和复制 sheetExcelValidator 和 ExcelTypeConverter(枚举/日期/基本类型转换)ExcelUtils 用于列字母/索引、样式提取、sheet 复制等辅助功能快速示例:
@ExcelSheet
@ExcelRow(startRowIndex = 1)
public class StudentExcelModel {
@ExcelColumn(col = "A", required = true)
public String name;
}
Workbook wb = WorkbookFactory.create(inputStream);
ImportResult<StudentExcelModel> result =
ExcelMapper.parseWorkbookWithResult(wb, StudentExcelModel.class, false);
使用模式和示例,请参见 spring-tools-simples README。
org.springtools.excel.annotation)在模型类上定义映射元数据:
@ExcelSheet
sheetName 指定要解析的 sheet(默认:第一个 sheet)@ExcelRow
startRowIndex:起始行(从 1 开始,通常第 0 行是表头,数据从第 1 行开始)skipRowByBlank:如果为 true 则跳过空行@ExcelSection
sectionKeyword:要搜索的关键字(例如 “学生列表”)keywordInCol:要搜索的列(例如 “A”)startRowIndex:找到关键字后要读取的行数stopKeyword:可选的停止关键字@ExcelColumn
col:列字母(例如 “A”、”B”、”AA”)required:验证标志unique:检查跨行唯一性uniqueByBlankCols:唯一性检查时忽略空白的列enumClass:用于枚举转换min、max:数值范围验证dateFormat:自定义日期解析格式regex:正则表达式验证ExcelMapper — 读取 Excel → Java 对象
主要方法:
parseWorkbook(Workbook, Class<T>) → List<T>(出错时抛异常)parseWorkbookWithResult(Workbook, Class<T>, boolean failFast) → ImportResult<T>(收集错误)parseWorkbookBySheet(Workbook, Class<T>, boolean includeEmpty) → Map<String, List<T>>parseSheetSection(Sheet, Class<T>) — 用于 @ExcelSection 模型ExcelExporter — 写入 Java 对象 → Excel 模板
主要方法:
fillTableRows(Sheet, int startRow, List<T> data, Class<T>) — 将数据填充到模板行fillSection(Sheet, sectionKeyword, keywordInCol, List<T>, Class<T>) — 填充区段copySheetWithStyles(Sheet source, Workbook target, String newName) — 克隆 sheet 及格式ExcelValidator
required、unique、min、max、regex)ValidationResultExcelMapper 内部使用ExcelTypeConverter
ExcelUtils — 底层辅助方法
colLetterToIndex("A") → 0,colLetterToIndex("AA") → 26colIndexToLetter(0) → “A”prepareBindings(Class<?>) → List<ColumnBinding>(基于反射,已缓存)getCellValue(Cell)、setCellValue(Cell, Object)copyStyle(Cell source, Cell target)copyRow(Row source, Row target)列映射使用 Excel 列字母(A、B、C、…、Z、AA、AB、…)。ExcelUtils.colLetterToIndex 将字母转换为 POI API 使用的 0 基索引。
注解使用从 1 开始的”自然”编号(第 1 行 = Excel UI 中的第一行)。调用 POI API 时,代码通常会执行 -1。
ExcelUtils.prepareBindings(Class) 读取 clazz.getDeclaredFields() 并缓存绑定。字段声明顺序当前很重要。考虑在未来版本中为 @ExcelColumn 添加 order() 以实现显式排序。
@ExcelSection 使用 sectionKeyword + keywordInCol 来定位数据块。ExcelMapper.parseSheetSection 扫描关键字,然后读取其下方的行,直到 stopKeyword 或 sheet 结束。
parseWorkbook(...) 在第一个错误时抛出异常(传统模式)parseWorkbookWithResult(..., failFast=false) 在 ImportResult<T> 中收集所有错误,包含 errors: List<ValidationResult>ValidationResult 包含行号、列、错误消息,便于用户友好的报告// 解析所有 sheet,出错时抛异常
List<T> parseWorkbook(Workbook workbook, Class<T> clazz)
// 解析并收集错误
ImportResult<T> parseWorkbookWithResult(Workbook workbook, Class<T> clazz, boolean failFast)
// 按 sheet 名称解析
Map<String, List<T>> parseWorkbookBySheet(Workbook workbook, Class<T> clazz, boolean includeEmpty)
// 解析基于区段的模型
List<T> parseSheetSection(Sheet sheet, Class<T> clazz)
// 填充模板行
void fillTableRows(Sheet sheet, int startRow, List<T> dataList, Class<T> clazz)
// 填充模板中的区段
void fillSection(Sheet sheet, String sectionKeyword, String keywordInCol,
List<T> dataList, Class<T> clazz)
// 克隆 sheet 及样式
Sheet copySheetWithStyles(Sheet sourceSheet, Workbook targetWorkbook, String newSheetName)
// 验证单个对象
ValidationResult validate(Object obj, int rowNum, Class<?> clazz)
// 验证列表(检查唯一性约束)
List<ValidationResult> validateList(List<T> list, Class<T> clazz)
// 将单元格值转换为目标类型
<T> T convertValue(Object value, Class<T> targetType, String dateFormat)
getDeclaredFields() 顺序。为确保跨编译器和重构的稳定性:
@ExcelColumn 添加 order() 属性RuntimeException。考虑添加:
ExcelParseExceptionValidationExceptionprepareBindings 现在使用缓存,但考虑:
regex 属性)skipRowByBlank、unique 约束参见 spring-tools-simples README 了解: