Skip to Content

数据导入

File Starter 支持两种导入模式:

  1. 按已配置模板导入ImportTemplate + ImportTemplateField

    • 支持下载模板
    • 通过所选模板提交上传文件
  2. 动态映射导入(无模板,在请求中提供映射)

    • 在浏览器中解析上传的 .xlsx 工作簿
    • 基于元数据自动将工作簿表头映射到模型字段
    • 允许用户在提交前调整映射关系

ImportTemplate 配置表

字段类型默认值说明
nameStringnull模板名称
modelNameStringnull要导入的模型名
importRuleImportRulenull导入规则:CreateOrUpdate / OnlyCreate / OnlyUpdate
uniqueConstraintsListnullCreateOrUpdate 使用的唯一键字段
ignoreEmptyBooleannull导入时是否忽略空值
skipExceptionBooleannull某一行失败时是否继续
customHandlerStringnullCustomImportHandler 对应的 Spring bean 名称
syncImportBooleannulltrue 时同步导入,否则异步导入
includeDescriptionBooleannull是否在模板输出中包含说明
descriptionStringnull说明文本
importFieldsListnull导入字段列表

ImportTemplateField 配置表

字段类型默认值说明
templateIdLongnullImportTemplate id
fieldNameStringnull模型字段名(支持 deptId.code 等关联反查)
customHeaderStringnull自定义 Excel 表头
sequenceIntegernull模板中的字段顺序
requiredBooleannull是否必填
defaultValueStringnull默认值(支持 {{ expr }}
descriptionStringnull说明文本

1. 按模板导入(已配置)

  1. 配置 ImportTemplateImportTemplateField

ImportTemplate 关键字段:

  • namemodelNameimportRule
  • uniqueConstraints(用于 CreateOrUpdate
  • ignoreEmptyskipExceptioncustomHandlersyncImport

ImportTemplateField 关键字段:

  • fieldNamecustomHeadersequencerequireddefaultValue

说明:

  • ImportTemplateField 的默认值支持占位符 {{ expr }}:简单变量从 env 解析,表达式在 env 上下文中求值。
  • syncImport = true,导入在当前进程内执行。
  • syncImport = false,会向 MQ 发送异步导入消息。

1.1 关联反查导入(级联导入)

ImportTemplateField 中的 fieldName(或动态导入中的 importFieldDTOList)支持通过 RelationLookupResolver 使用点路径关联反查。无需导入原始外键 id,可导入关联模型的可读业务键,系统会自动反查并写入外键 id。

语法: {外键字段}.{业务键} — 例如 deptId.codedeptId.name

工作机制:

  1. 系统识别根为 ManyToOne/OneToOne 的点路径字段。
  2. 按根外键字段分组(例如 deptId.codedeptId.name 同属 deptId 一组)。
  3. 按业务键值批量查询关联模型以解析外键 id。
  4. 将解析到的外键 id 写回根字段(deptId),并移除点路径列。

规则:

  • 仅支持单层级联:deptId.code ✅,deptId.companyId.code
  • 同一模板中,直接外键字段(如 deptId)与反查字段(如 deptId.code不能同时存在
  • 多个反查字段共享同一根时,组合为复合业务键(例如 deptId.code + deptId.name 共同唯一确定一条 Department)
  • 当一行中所有反查值为空时:
    • ignoreEmpty = true:跳过该外键字段(不写入)
    • ignoreEmpty = false:明确将外键字段置为 null
  • 当反查失败(无匹配记录)时:
    • skipException = true:该行标记失败并附带原因
    • skipException = false:立即抛出 ValidationException

示例 — 按模板导入:

ImportTemplateField 配置:

fieldName: "deptId.code" customHeader: "Department Code" sequence: 3 fieldName: "name" customHeader: "Employee Name" sequence: 1 fieldName: "jobTitle" customHeader: "Job Title" sequence: 2

Excel:

Employee NameJob TitleDepartment Code
AliceEngineerD001
BobManagerD002

系统将按 code = "D001" / "D002" 查找 Department,解析 id 并写入 deptId

示例 — 动态导入(含关联反查):

curl -X POST http://localhost:8080/import/dynamicImport \ -F file=@/path/to/employees.xlsx \ -F 'wizard={ "modelName":"Employee", "importRule":"CreateOrUpdate", "uniqueConstraints":"employeeCode", "importFieldDTOList":[ {"header":"Employee Name","fieldName":"name","required":true}, {"header":"Department Code","fieldName":"deptId.code","required":true}, {"header":"Job Title","fieldName":"jobTitle"} ], "syncImport":true };type=application/json'
  1. 下载模板文件(可选)

接口:

  • GET /ImportTemplate/getTemplateFile?id={templateId}

生成的模板使用字段标签作为表头,必填列带样式。

  1. 按模板导入

接口:

  • POST /import/importByTemplate

参数:

  • templateIdImportTemplate id
  • file:Excel 文件
  • env:环境变量 JSON 字符串

示例:

curl -X POST http://localhost:8080/import/importByTemplate \ -F templateId=1001 \ -F env='{"deptId": 10, "source": "manual"}' \ -F file=@/path/to/import.xlsx

2. 动态映射导入(无模板)

接口:

  • POST /import/dynamicImport

该接口接受 multipart/form-data,包含:

  • file:上传的 Excel 文件
  • wizardImportWizard 的 JSON payload

关键字段:

  • modelName
  • importRuleCreateOrUpdate | OnlyCreate | OnlyUpdate
  • uniqueConstraints:逗号分隔的字段名
  • importFieldDTOList:表头到字段的映射列表
  • ignoreEmptyskipExceptioncustomHandlersyncImport

示例:

curl -X POST http://localhost:8080/import/dynamicImport \ -F file=@/path/to/import.xlsx \ -F 'wizard={ "modelName":"Product", "importRule":"CreateOrUpdate", "uniqueConstraints":"productCode", "importFieldDTOList":[ {"header":"Product Code","fieldName":"productCode","required":true}, {"header":"Product Name","fieldName":"productName","required":true}, {"header":"Price","fieldName":"price"} ], "syncImport":true };type=application/json'

3. 导入结果与失败行

  • 导入返回 ImportHistory
  • 若任意一行失败,会生成并保存「失败数据」Excel,其中包含 Failed Reason 列。
  • 导入状态可为 PROCESSINGSUCCESSFAILUREPARTIAL_FAILURE

4. 自定义导入处理器

可注册实现了 CustomImportHandler 的 Spring bean,并在 ImportTemplate.customHandlerImportWizard.customHandler 中按名称引用。

import io.softa.starter.file.excel.imports.CustomImportHandler; @Component("productImportHandler") public class ProductImportHandler implements CustomImportHandler { @Override public void handleImportData(List<Map<String, Object>> rows, Map<String, Object> env) { // custom preprocessing } }

约定:

  • 可以原地修改行值。
  • 可通过写入 FileConstant.FAILED_REASON 将某一行标记为失败。
  • 不要新增、删除、重排或替换行对象。
最后更新于