在 2026-09-14 的
framwork-excel更新中,实现了针对异步导入的@NotEmpty注解效果,它可以自动在模板表头补充*,并支持自动空值校验。同时,框架还提供了
@ExcelTemplateIgnore注解,在模板 DTO 基类中使用,带有该注解的字段不会出现在下载的导入模板中,但会出现在导入结果文件内。
异步导入里 @NotEmpty 要生效,需要满足下面这些条件(按链路分层说明)。
1. 接入条件(框架层)
| 条件 | 说明 |
|---|---|
Handler 继承 AbstractImportHandler |
execute() 里会调用 ImportNotEmptyRowValidator.preprocess |
super(..., className) 传对映射类 |
单 Sheet 传行 DTO;多 Sheet 传带 @ManySheet 的聚合类(如 PartMultiSheetExcelTemplateDTO) |
| 走标准异步读入 | ExcelReadUtil 已注册 NotEmptyHandler,负责表头 * 剥除与列映射 |
public PartImportHandler() {
super("partImport", "物料导入", PartMultiSheetExcelTemplateDTO.class.getName());
}
2. 注解条件(字段层)
必须用框架注解,且与 @ExcelProperty 成对出现:
import com.sie.mbm.mom.framework.common.annotation.NotEmpty; // 不是 jakarta.validation
private static List<Field> collectNotEmptyFields(Class<?> rowClass) {
return collectAllFields(rowClass).stream()
.filter(field -> field.isAnnotationPresent(NotEmpty.class))
.filter(field -> field.isAnnotationPresent(ExcelProperty.class))
.collect(Collectors.toList());
因此:
- 只加
@NotEmpty、没有@ExcelProperty→ 不校验(聚合类上List<...>字段上的@NotEmpty无效) - 用了
jakarta.validation.constraints.NotEmpty→ 不校验(预处理器只认框架注解) @ExcelProperty列名不要手写*,写逻辑名即可,NotEmptyHandler会在模板写出时补*
推荐写法(物料示例):
@ExcelProperty("物料编码")
@NotEmpty
@Schema(description = "物料编码")
private String code;
@ExcelProperty("物料名称")
@NotEmpty
@Schema(description = "物料名称")
private String name;
3. 行 DTO 结构条件
| 条件 | 作用 |
|---|---|
继承 AsyncImportRowSupport |
失败行写入 checkResult=0、checkMsg=xxx,结果 Excel 有「导入结果 / 导入结果信息」 |
结果列带 @ExcelTemplateIgnore |
基类已处理,模板下载/读入时排除结果列 |
多 Sheet 时 @ManySheet(sheetName = "...") 与 Excel Sheet 名一致 |
否则读不到数据,校验也不会跑 |
不继承 AsyncImportRowSupport 时,预处理器会尝试反射写 checkResult / checkMsg,但结果列契约不完整,不推荐。
4. 运行时行为(理解约束)
预处理在 doImport 之前执行:
读 Excel → NotEmpty 预处理 → 仅通过行进入 doImport → 合并失败行写回结果
| 行类型 | 行为 |
|---|---|
全空行(所有 @ExcelProperty 字段都空) |
静默丢弃,不进结果、不进 doImport |
有数据但 @NotEmpty 字段为空 |
标记失败,写 导入结果信息,不进 doImport |
| 全部通过 | 进入 doImport |
| 全部失败 | skipDoImport=true,只出结果文件 |
空值判定:null 或空白字符串(StrUtil.isBlank)。
5. Handler 侧约定
@NotEmpty覆盖的字段,不需要在doImport里再写一遍空值判断(避免重复、消息不一致)- 业务规则校验(编码是否存在、枚举是否合法等)仍留在 Handler
6. 最小 checklist
XxxImportHandler extends AbstractImportHandler- 行 DTO
extends AsyncImportRowSupport - 必填字段:
@ExcelProperty("列名")+@NotEmpty(框架包) - 多 Sheet:聚合类
@ManySheet+ 行 DTO 放List<RowDto>里 - 模板下载走
ExcelDropDownUtil(自动补*) - Handler 删掉与
@NotEmpty重复的空值校验
满足以上条件后,异步导入会自动完成:必填校验 → 失败行落结果 → 通过行执行业务导入。