任欢
Published on 2026-09-14 / 24 Visits
0
0

异步导入中 @NotEmpty 注解的条件和用法

在 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

  1. XxxImportHandler extends AbstractImportHandler
  2. 行 DTO extends AsyncImportRowSupport
  3. 必填字段:@ExcelProperty("列名") + @NotEmpty(框架包)
  4. 多 Sheet:聚合类 @ManySheet + 行 DTO 放 List<RowDto> 里
  5. 模板下载走 ExcelDropDownUtil(自动补 *)
  6. Handler 删掉与 @NotEmpty 重复的空值校验

满足以上条件后,异步导入会自动完成:必填校验 → 失败行落结果 → 通过行执行业务导入。


Comment