Excel 导入配置(ExcelConfig / IMPMappingConfig)定义编写指南¶
目标:Agent 直接生成/修改 workspace Excel 导入配置。知识以本文为准。不写原理;不依赖外链。
硬规则(生成范围)¶
- 只生成
templateType=EXCEL_JSON,内容写在jsonTemplate(CDATA,合法 JSON 字符串)。 - **禁止**新建、补写或把配置改成
EXCEL_XML/ 空templateType+<xml>(ExcelMappingDiagram)。 - 存量应用里若已有 XML 配置:可保留不碰;需要新能力时 新建 JSON 配置 替换绑定,勿再扩写 XML。
- 落盘时 省略或留空
<xml>;normalizeBeforeSave在 JSON 模式下会清空xml。
iScript:JSON 路径优先字段 validationRule / transform;一般不写列级 valueScript/validateRule。若确需脚本场景,再读 iscript-usage → excelimport.md。
术语:实体类 cn.myapps.core.common.model.excelimport.IMPMappingConfigVO;产品「Excel 导入配置 / 高级工具-Excel 导入」。是软件级 Excel→表单/库表 映射定义;不是**视图「导出 Excel」动作(ActivityType.EXPTOEXCEL=16),**不是 .xlsx 文件本体(样例路径只在 templatePath)。
依赖:挂在**软件(Application)下;parentId=软件 id。运行时由视图操作 **type=27(导入 Excel) 的 impmappingconfigid 引用本配置 id。
产出物一览¶
| 部分 | 落盘 | 形态 |
|---|---|---|
| Excel 导入配置 | excelconfig/{配置名}.excelconfig |
单文件;JAXB 根 impMappingConfigVO;id 为根属性 |
路径相对 storage/workspace。
常量(ModelSuffix) |
值 |
|---|---|
EXCEL_IMPORT_CFG_PATH_SUFFIX / EXCEL_IMPORT_CFG_FILE_SUFFIX |
excelconfig |
EXCEL_IMPORT_CFG_FILE_GROUP |
/excelconfig |
ModelSuffixEx:后缀 → IMPMappingConfigVO.class。DAO:FileSystemIMPMappingConfigDAO。
新建最低配置:
- 目录存在:
{软件}.application/excelconfig/ - 写
{name}.excelconfig:id、name、parentId=软件 id、templateType=EXCEL_JSON、非空jsonTemplate(合法 JSON,CDATA) jsonTemplate至少含 1 个sheetType=master的 Sheet +fieldList非空;表单目标填formId;库表目标填dataSourceId+targetTableId- (可选)
templatePath指向已上传.xlsx;无则运行态可对EXCEL_JSON动态export-excel - 视图操作
.activity:type=27,impmappingconfigid=本配置 id - **不要**写
<xml>/EXCEL_XML
约定:
- JAXB;根
impMappingConfigVO;id在 根属性 description/jsonTemplate用 CDATA(CDataAdapter)- 文件名 =
name+.excelconfig;同软件excelconfig/下 name 不重名 name勿含/%\(落盘替换=47/=37/=92)parentId= 软件 id;applicationid基类常无@XmlElement,落盘常缺;API 保存会 set- **勿**放到
module/下;永远在应用级excelconfig/ validateBeforeSave:jsonTemplate非空且JSONObject.fromObject可解析
1. 心智模型¶
软件 Application
└─ excelconfig/*.excelconfig ← IMPMappingConfigVO
templateType=EXCEL_JSON
jsonTemplate(CDATA) → TemplateJson / JsonTemplate
视图 .view/{操作}.activity
type=27,impmappingconfigid = 配置 id
│
▼ 前台 excel_upload.vue
上传 path → validationExcel? → importExcel(轮询 readProcess)
│
▼ ExcelImportRuntimeServiceImpl → JsonImportProvider
样例模板:
templatePath 静态文件 或 GET .../excelimport/{id}/export-excel
| 概念 | 说明 |
|---|---|
配置 IMPMappingConfigVO |
应用下一条导入映射;列表/绑定用 id/name |
templateType |
固定写 EXCEL_JSON(本文生成范围) |
jsonTemplate |
设计器 TemplateJson 字符串(不是嵌套 XML) |
templatePath |
样例 .xlsx 相对路径;可空则动态导出 |
视图 impmappingconfigid |
绑定本配置 id;缺则无法导入 |
| 导出 Excel(视图数据) | 另一动作 type=16;不读 .excelconfig |
易混:
| 对象 | 位置 | 用途 |
|---|---|---|
.excelconfig |
应用 excelconfig/ |
导入映射(本文) |
Activity type=27 |
.view/*.activity |
前台触发导入 |
Activity type=16 |
.view/*.activity |
导出当前视图数据 |
templatePath / export-excel |
uploads 或动态流 | 空白导入模板,非业务数据导出 |
2. IMPMappingConfigVO 属性 → .excelconfig XML¶
属性表(生成时填写)¶
| 属性 | XML | 类型 | 默认/样例 | 说明 |
|---|---|---|---|---|
id |
根属性 | string | 须生成 | __ + 短 UUID;即 impmappingconfigid。jsonTemplate 内 Sheet/字段 id 可用短 UUID(可带或不带 __) |
name |
子元素 | string | — | 必填;文件名;应用内唯一;导出模板文件名常用此名 |
parentId |
子元素 | string | — | = 软件 id |
applicationid |
常不落盘 | string | API 侧 = 软件 id | |
description |
CDATA | string | 可空 | 说明 |
templateType |
子元素 | string | EXCEL_JSON |
生成时必填此值 |
jsonTemplate |
CDATA | string | — | 必填;TemplateJson 文本 |
templatePath |
子元素 | string | 可空 | 如 /resources/exceltemplate/xxx.xlsx |
常量:
IMPMappingConfigVO.TYPE_EXCEL_JSON = "EXCEL_JSON"
isExcelJsonTemplate() ← TYPE_EXCEL_JSON.equals(templateType)
id 生成¶
统一规则:__ + 短 UUID。示例:__MpEzTToulqZtNEFisw6。勿与其它配置/资源冲突。改 id 须同步所有视图 impmappingconfigid。
设计态校验 / 保存¶
| 条件 | 效果 |
|---|---|
name 空 |
标准 name 校验 |
| 同应用同名 | doSaveValidate 名称唯一失败 |
jsonTemplate 空 |
JSON 模板内容不能为空 |
jsonTemplate 非合法 JSON |
JSON 模板格式无效 |
| PUT 未带模板字段 | mergeOnUpdate 保留原 jsonTemplate/templatePath/description |
类/服务:
| 角色 | 类 |
|---|---|
| Controller | cn.myapps.designtime.dts.excelimport.config.controller.ExcelConfigsController |
| Service | IMPMappingConfigDesignTimeService / Impl |
| DAO | FileSystemIMPMappingConfigDAO |
| DesignTime 获取 | DesignTimeServiceManager.impMappingConfigDesignTimeService() |
API 基路径:/api/designtime/applications/{applicationId}/excelconfigs
| 方法 | 路径 | 作用 |
|---|---|---|
| GET | .../excelconfigs |
列表;name/pageNo/linesPerPage |
| GET | .../excelconfigs/{id} |
详情 |
| POST | .../excelconfigs |
新建;强制 parent/applicationid |
| PUT | .../excelconfigs/{id} |
更新(merge) |
| DELETE | .../excelconfigs |
body=id 数组 |
| GET | .../excelconfigs/{id}/export-excel |
按已存 JSON 导出 .xlsx |
| POST | .../excelconfigs/export-excel |
预览导出(body=TemplateJson 或包装) |
3. jsonTemplate(TemplateJson / JsonTemplate)¶
前端类型名 TemplateJson;后端 cn.myapps.core.runtime.dynaform.dts.excelimport.json.model.JsonTemplate。结构同构。落盘是字符串(整段 JSON 进 CDATA),不是子 XML。
根对象¶
{
"templateName": "配置显示名",
"templateDesc": "",
"sheets": [ /* ExcelSheet */ ],
"config": {
"showRequiredMark": true,
"openValidateTip": true,
"excelRowHeight": 15
}
}
| 字段 | 类型 | 说明 |
|---|---|---|
templateName |
string | 模板名;可与配置 name 同 |
templateDesc |
string | 描述 |
sheets |
array | 至少 1 个 master |
config.showRequiredMark |
bool | 导出表头必填列追加 * |
config.openValidateTip |
bool | 导出数据验证提示 |
config.excelRowHeight |
int | 全局行高 pt;样例/前端常用 15(手写请显式写 15) |
Sheet(JsonExcelSheet)¶
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
id |
string | __ + 短 UUID |
Sheet 前端 id |
name |
string | — | Excel Sheet 名;最长 31;运行按名匹配工作表 |
exportTarget |
string | form |
form | database |
moduleId |
string | 表单模式选模块(设计器用) | |
formId |
string | form 时必填:表单 id(非 name) |
|
dataSourceId |
string | database 时必填 |
|
targetTableId |
string | database 时必填:目标表名/id |
|
sheetType |
string | master |
master | detail;全局仅一个 master 语义 |
fieldList |
array | 非空;列序=Excel 列序 | |
labelRows |
array | 多级表头;可空则导出用字段 name 作表头 |
|
dataRow |
object | { height, isExample, style? } |
ImportPlanBuilder 校验:
- 无 master →
JSON 模板缺少主 Sheet - Sheet
name空 /fieldList空 / 字段缺key→ 抛错 - form 缺
formId;database 缺dataSourceId或targetTableId→ 抛错
数据起始行:dataStartRowIndex = sheet.getDisplayLabelLevelCount()(labelRows 最大 rowLevel,无标签但有字段时至少 1)。导入跳过标签行后从该索引起读数据。
字段(JsonFieldItem / ExcelFieldItem)¶
| 字段 | 类型 | 默认 | 说明 |
|---|---|---|---|
id |
string | __ + 短 UUID |
前端列 id |
key |
string | — | 绑定键:表单字段 name 或库表列名 |
name |
string | — | 表头/展示名 |
required |
bool | false | 必填;导出 allowBlank=false |
dataType |
string | string |
见下表 |
validationRule |
string | none |
none/numberRange/dateRange/textLength/regex |
lengthLimit |
[min,max] |
文本长度或数值范围 | |
dateRange |
[start,end] |
日期/日期时间 ISO | |
timeRange |
[start,end] |
HH:mm |
|
pattern / patternTip |
string | 正则与提示 | |
fillMode |
string | input |
input | select |
selectOptions |
string[] | 下拉候选项 | |
numberFormat / dateFormat / timeFormat / datetimeFormat |
string | Excel 格式串 | |
defaultValue |
string | 示例行填充 | |
transform |
Record<string,string> |
{} |
值映射转换 |
relation |
object | 仅 detail:{masterKey,detailKey} |
|
primaryKey / isPrimaryKey |
bool | false | 主键;存在则更新;二者任一 true 即生效(isPrimaryKeyField()) |
dataType:string | number | date | time | datetime | phone | email | idCard
格式串常用值:
| 类型 | 常用 format |
|---|---|
| number | #,##0;-#,##0 / #,##0.00;-#,##0.00(可带 [Red]) |
| date | yyyy/m/d;中文 [DBNum1][$-804]yyyy"年"m"月"d"日" |
| time | h:mm / h:mm:ss / mm:ss.0 |
| datetime | yyyy/m/d h:mm / yyyy-mm-dd hh:mm:ss |
主从:detail 字段 relation.masterKey = 主 Sheet 某 key;relation.detailKey 应 = 本列 key。ImportPlanBuilder 取 第一个 配齐 masterKey+detailKey 的 relation 作为该 detail Sheet 关联。
旧版 JSON 若含从 Sheet 级 relationField(仅主表 key),前端可能迁移到首个未配置 relation 的字段;手写请直接用字段级 relation。
列标签(labelRows / JsonColumnLabelCell)¶
| 字段 | 说明 |
|---|---|
id |
__ + 短 UUID |
columnIndex |
0-based 对 fieldList |
rowLevel |
1-based L1/L2… |
text |
标签文案 |
align |
left/center/right |
colspan / rowspan |
默认 1 |
style |
LabelCellStyle:fontSize(pt 默认 11)、fontWeight、fontStyle/fontItalic、textDecoration、color、backgroundColor |
默认标签风:fontSize=11,color=#2e7d32,backgroundColor=#e8f5e9。
数据行(dataRow)¶
| 字段 | 说明 |
|---|---|
height |
pt;前端默认 15 |
isExample |
true 时导出首行填 defaultValue |
style |
对象或 JSON 字符串 → JsonCellStyle |
JSON 运行写入¶
exportTarget |
写入 |
|---|---|
form |
JsonFormImporter → DocumentProcess.doCreateOrUpdate4ExcelImport(按 formId) |
database |
JsonDatabaseImporter → JDBC insert/update(主键列存在则更新) |
校验链:JsonFieldValidator(必填/类型/下拉/范围/正则)+ JsonFieldValueConverter。进度键复用 AbstractImportProvider(readProcess 不变)。
服务端按 JSON 生成 .xlsx 要点¶
- 每 Sheet → POI Sheet,名=
name - 写
labelRows+ 合并;无标签用field.name(showRequiredMark加*) - 数据区预置 500 行格式(
TEMPLATE_FORMAT_ROW_COUNT) validationRule=none不写验证,但fillMode=select仍写下拉- 设计器辅助行(字段名行、列字母)不导出
4. 完整 .excelconfig 样例¶
4.1 库表导入¶
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<impMappingConfigVO id="__PpQV6dAHfQOxEAA3Akj">
<name>excel-table</name>
<parentId>sOZu9kthmxyP8qQfq0e</parentId>
<description><![CDATA[]]></description>
<templateType>EXCEL_JSON</templateType>
<jsonTemplate><![CDATA[{"templateName":"excel-table","templateDesc":"","sheets":[{"id":"ca581154-672a-4bb2-af8b-376d4b230e65","name":"主表","exportTarget":"database","moduleId":"","formId":"","dataSourceId":"rDXojBcjqZudUraN1Yc","targetTableId":"EXCEL_MASTER","sheetType":"master","fieldList":[{"id":"922f0106-c5a1-46c9-9529-f653b6ab34ae","key":"ITEM1","name":"ITEM1","required":false,"dataType":"string","fillMode":"input","validationRule":"none"},{"id":"6ca4abc4-e359-4f20-9de5-e73039ed2e1a","key":"ITEM2","name":"ITEM2","required":false,"dataType":"string","fillMode":"input","validationRule":"none"}],"labelRows":[{"id":"7d26c9f3-ed49-4038-b1d1-1cc0323c5ab1","columnIndex":0,"rowLevel":1,"text":"ITEM1","align":"center","colspan":1,"rowspan":1,"style":{"fontWeight":"normal","fontStyle":"normal","textDecoration":"none","backgroundColor":"#e8f5e9","color":"#2e7d32","fontSize":11}},{"id":"fc0587b5-dbf1-40d8-b381-bb56a1e70080","columnIndex":1,"rowLevel":1,"text":"ITEM2","align":"center","colspan":1,"rowspan":1,"style":{"fontWeight":"normal","fontStyle":"normal","textDecoration":"none","backgroundColor":"#e8f5e9","color":"#2e7d32","fontSize":11}}],"dataRow":{"height":15,"isExample":false}}],"config":{"showRequiredMark":true,"openValidateTip":true,"excelRowHeight":15}}]]></jsonTemplate>
</impMappingConfigVO>
4.2 表单导入最小 jsonTemplate(单 Sheet、两列)¶
{
"templateName": "订单导入",
"templateDesc": "",
"sheets": [{
"id": "sheet-master-1",
"name": "主表",
"exportTarget": "form",
"moduleId": "{模块id}",
"formId": "{表单id}",
"sheetType": "master",
"fieldList": [
{"id": "f1", "key": "orderNo", "name": "订单号", "required": true, "dataType": "string", "fillMode": "input", "validationRule": "none", "primaryKey": true},
{"id": "f2", "key": "amount", "name": "金额", "required": false, "dataType": "number", "fillMode": "input", "validationRule": "none", "numberFormat": "#,##0.00;-#,##0.00"}
],
"labelRows": [
{"id": "l1", "columnIndex": 0, "rowLevel": 1, "text": "订单号", "align": "center", "colspan": 1, "rowspan": 1, "style": {"fontSize": 11, "color": "#2e7d32", "backgroundColor": "#e8f5e9"}},
{"id": "l2", "columnIndex": 1, "rowLevel": 1, "text": "金额", "align": "center", "colspan": 1, "rowspan": 1, "style": {"fontSize": 11, "color": "#2e7d32", "backgroundColor": "#e8f5e9"}}
],
"dataRow": {"height": 15, "isExample": false}
}],
"config": {"showRequiredMark": true, "openValidateTip": true, "excelRowHeight": 15}
}
4.3 主从 detail 列示例¶
{
"key": "order_id",
"name": "订单ID",
"dataType": "string",
"required": true,
"validationRule": "none",
"fillMode": "input",
"relation": { "masterKey": "id", "detailKey": "order_id" }
}
落盘时 jsonTemplate 须为**单行合法 JSON**(进 CDATA);可读排版仅用于编辑,写入文件前压成一行。
5. 视图操作绑定(消费方)¶
路径:{视图名}.view/{操作名}.activity;根 <activity>。
| 元素 | 值 |
|---|---|
type |
27(ActivityType.EXCEL_IMPORT) |
impmappingconfigid |
配置 id(不是 name) |
parentView |
视图 id |
另:type=16 导出 Excel **不要**填 impmappingconfigid(视图列/查询导出)。
运行时 View 下发:Activity.excelTemplate ← 配置 templatePath(加密);templatePath 空时可走动态 export-excel。
6. 运行态导入 / 校验 / 进度¶
基路径:/api/runtime
| 方法 | 路径 | 作用 |
|---|---|---|
| POST | /{appId}/views/{viewId}/activities/importExcel?excelImportTime= |
导入;body 含 impmappingconfigid/path/actId/exparams |
| POST | /{appId}/views/{viewId}/activities/validationExcel?excelValidateTime= |
仅校验 |
| GET | /importExcel/readProcess?excelImportTime= |
导入进度 |
| GET | /validateExcel/readProcess?excelValidateTime= |
校验进度 |
| GET | /{appId}/excelimport/{configId}/export-excel |
JSON 配置动态模板(运行时加密 id) |
body 要点:
{
"impmappingconfigid": "__impConfig001",
"path": "/uploads/excel/20260710/order.xlsx",
"actId": "__actImport001",
"parentId": "",
"exparams": { "appId": "...", "formId": "...", "docid": "", "parentId": "", "isRelate": false }
}
成功:errcode=0。失败校验/导入:errcode=4001,data 多条错误用 $$ 拼接。错误形态常见:工作表名 {Row}[行号]: 详情。
本文生成的配置一律走 vo.isExcelJsonTemplate() → ExcelImportRuntimeServiceImpl → JsonImportProvider。finally 删临时 Excel。
前台:excel_upload.vue + api.js(importExcel / importExcelProgress)。
7. templatePath 与模板下载¶
| 方式 | 说明 |
|---|---|
| 上传 | POST /api/designtime/applications/{appId}/uploads?path=... → 回写 filePath 到 templatePath |
| 服务端生成后上传 | export-excel 得 .xlsx → 再 upload → 写 path |
| 运行静态下载 | templatePath → encrypt → DownloadController |
| 运行动态 | path 空:GET .../excelimport/{configId}/export-excel |
下载文件名:配置 name + .xlsx(设计态 GET export;运行动态同)。
8. 字段校验(JSON)¶
优先用字段内置能力,勿为「生成配置」去写旧版列脚本:
| 需求 | 用法 |
|---|---|
| 必填 | required: true |
| 类型 | dataType:string/number/date/phone/email/idCard 等 |
| 范围/长度/正则 | validationRule + lengthLimit / dateRange / pattern |
| 下拉 | fillMode: "select" + selectOptions |
| 值映射 | transform |
| 主键更新 | primaryKey 或 isPrimaryKey |
9. 设计器宿主桥(生成配置时可选上下文)¶
HostRequestBridge(组件不直连后端):
| 方法 | 典型 HTTP |
|---|---|
getModules() |
GET .../modules?parentId={appId} |
getModuleForms(moduleId) |
GET .../modules/{moduleId}/forms |
getFormSchema(moduleId, formId) |
GET .../print/form-schema?moduleId=&formId=(name/label) |
getAppDataSources(appId) |
GET .../datasources |
getDataSourceTables |
GET .../datasources/metadatas?datasourceId=&subNodes=isTables |
getDataSourceTableSchema |
GET .../datasources/{dsId}/forms/{tableId}/info |
保存:templateType=EXCEL_JSON + jsonTemplate 字符串。
10. 与其它技能边界¶
| 内容 | 本文 | 其它 |
|---|---|---|
.excelconfig 字段、JSON 模板、路径、绑定 id |
✓ | |
软件目录 excelconfig/ 存在性 |
交汇 | APPLICATION_SKILL |
视图 type=27 activity 文件结构 |
交汇 | VIEW_SKILL |
| 表单字段 name / formId | key/formId 取值 |
FORM_SKILL |
| 数据源 id / 目标表 | database 模式 | DATASOURCE_SKILL |
| MODULE 下「可能出现 excelconfig」表述 | 否(现行 FILE_GROUP 在应用级) | MODULE_SKILL 历史备注忽略 |
| 视图导出 Excel type=16 | 否 | VIEW_SKILL / Activity |
| 新建 EXCEL_XML / ExcelMappingDiagram | 否(禁止) | — |
附录 A:后缀与根元素¶
| 项 | 值 |
|---|---|
| 根元素 | impMappingConfigVO |
| 文件后缀 | .excelconfig |
| 分组目录 | excelconfig/ |
| VO FQCN | cn.myapps.core.common.model.excelimport.IMPMappingConfigVO |
@XmlType(name) |
IMPMappingConfigVO |
| 生成用 templateType | EXCEL_JSON |
附录 B:运行/设计关键类速查¶
设计态:ExcelConfigsController, IMPMappingConfigDesignTimeServiceImpl
运行:ExcelImportRuntimeServiceImpl, TemplateJsonParser, ImportPlanBuilder,
JsonImportProvider, JsonFormImporter, JsonDatabaseImporter,
JsonExcelReader, JsonFieldValidator, JsonFieldValueConverter
模板导出:ExcelTemplateExportServiceImpl, ExcelTemplateBuilder, ExcelTemplateStyleHelper
附录 C:常见失败¶
| 现象 | 原因 |
|---|---|
| 导入找不到配置 | impmappingconfigid ≠ 文件 id;配置不在该应用 |
| 找不到表单 | formId 错或空;或误填表单 name |
| JSON 保存失败 | jsonTemplate 非法 JSON / 空 |
| JSON 导入缺列/键 | fieldList 空或 key 空 |
| 主从明细挂不上 | detail 无 relation 或 masterKey/detailKey 空 |
| 库表导入失败 | 缺 dataSourceId/targetTableId;DS 不可用 |
| 样例下不了 | templatePath 空且动态 export 失败 / 文件不存在 |
| 根元素错 | 必须 impMappingConfigVO |
| id 写成子元素 | 改为根属性 |
| 放进 module | 移到应用级 excelconfig/ |
| 与「导出 Excel」混淆 | type16 ≠ type27 |
| 误生成了 XML 模板 | 违反本技能硬规则;改为 EXCEL_JSON + jsonTemplate |
附录 D:生成检查清单¶
- 路径:
storage/workspace/{软件}.application/excelconfig/{name}.excelconfig - 根
<impMappingConfigVO id="...">;name=文件名去后缀;parentId=软件 id -
templateType=EXCEL_JSON;无<xml>/EXCEL_XML -
jsonTemplateCDATA 合法;有 master;form→formId或 database→源+表;字段key齐 - 视图存在
type=27且impmappingconfigid=配置 id - 同应用 name 不冲突;目标表单/表/数据源在环境中存在
- 若需前台下载样例:填
templatePath或依赖动态 export