用 SpreadJS 数据验证实现省市区三级联动

地址、商品分类、组织架构、费用科目都有一个共同特点:下一级选项取决于上一级选择。用户选了省份,城市列表就不应该再出现其他省的城市;选了城市,区域也应该随之收窄。三级联动 这个 demo 用 SpreadJS 的数据验证、自定义名称和 INDIRECT 函数组合,在普通单元格里实现省份、城市、区域三级下拉。

为什么这个细节重要

级联下拉解决的是数据质量问题。让用户自由输入省市区,后续清洗会很痛苦;让用户从完整城市列表里找,也不够友好。产品经理需要的是更低的填错概率,开发者需要的是一套能维护的数据源结构,业务用户需要的是"我选完上一级,下一级自然变对"。

这个 demo 的优势是它没有写复杂的弹窗控件,而是沿用电子表格里的数据验证能力。用户仍然在单元格里选择,表格仍然可以复制、粘贴、保存,联动规则则由公式引用完成。

这也让它更适合嵌入已有模板。很多企业表单已经围绕行列设计好了权限、导入和导出流程,级联下拉如果仍然发生在单元格内部,就不会破坏原来的工作方式。

SpreadJS 的实现思路

代码创建了一个名为"级联数据源"的工作表,把树形地址数据展开到不同列。第一列存所有省份;每个省份对应一列城市;每个"省份+城市"再对应一列区域。关键是用 sheet.addCustomName 给这些区域命名,并用 GC.Spread.Sheets.CalcEngine.rangesToFormula 生成绝对引用。

复制代码
sourceSheet.name("级联数据源");
​
let prRange = new GC.Spread.Sheets.Range(1, 0, source.length, 1);
sourceSheet.addCustomName(
  "省份",
  "级联数据源!" + GC.Spread.Sheets.CalcEngine.rangesToFormula(
    [prRange], 0, 0,
    GC.Spread.Sheets.CalcEngine.RangeReferenceRelative.allAbsolute,
    false
  )
);

主表三列分别是省份、城市、区域。省份列直接引用名称"省份";城市列使用 INDIRECT 拼出"级联数据源! + 当前行 A 列值";区域列再拼接 A 列和 B 列,找到对应区域列表。

复制代码
let provinceList =
  GC.Spread.Sheets.DataValidation.createFormulaListValidator("级联数据源!省份");
sheet.setDataValidator(1, 0, 10, 1, provinceList);
​
let cityList =
  GC.Spread.Sheets.DataValidation.createFormulaListValidator(
    'INDIRECT("级联数据源!"&$A2)'
  );
sheet.setDataValidator(1, 1, 10, 1, cityList);

可以扩展到哪些场景

省市区只是最容易理解的例子。同样方法可以用于商品大类、中类、小类,部门、岗位、人员,费用一级科目、二级科目、明细科目,设备类型、型号、点位。只要层级清晰、选项数量适中,这种基于数据源表和名称的方案就比较好维护。

需要注意,自定义名称要避免冲突。demo 用"省份+城市"作为区域名称,如果业务里存在重名城市,就要引入编码或更稳定的 key。数据量特别大时,也可以考虑自定义 CellType 或服务端查询式下拉。

实际交付时,还建议监听上级单元格变化并清空下级旧值。否则用户先选了"广东省-广州市",再把省份改成"浙江省",城市列可能还保留旧城市,形成看似合法但业务不一致的组合。如果要支持批量粘贴,也要在粘贴后重新校验三列组合,避免绕过下拉选择产生脏数据。

给开发者的关键词

SpreadJS、DataValidation、createFormulaListValidator、addCustomName、INDIRECT、GC.Spread.Sheets.Range、rangesToFormula、三级联动、省市区下拉、JavaScript 电子表格控件。

小结

三级联动 展示了 SpreadJS 里很"电子表格原生"的交互方式:用数据验证限制输入,用自定义名称管理候选集,用公式把上下级选项连起来。它让表格录入更稳,也让层级数据维护留在工作簿结构里。

相关推荐
派小心.1 小时前
A/B实验分层随机种子的稳定性验证
大数据·服务器·前端·数据分析
袋鼠云数栈UED团队1 小时前
从 Skills 到可靠的 Bugfix Agent
前端
幼儿园蛋小黑2 小时前
SPI 子系统:从原理到实践
java·前端·数据库
Data analyse4562 小时前
rrweb回放事件资源加载顺序重放校验
前端·人工智能·算法·机器学习·数据分析
lexiangqicheng2 小时前
自定义表单跨端共用机制-PC设计APP渲染
java·前端·javascript
zhikouai2 小时前
AI辅助逆向工程链路:从二进制接入到等价性校验
java·linux·前端
沙漏无语2 小时前
pnpm 安装@vue-office包的幽灵依赖问题解决
前端·javascript·vue.js
霍格沃兹测试学院-小舟畅学2 小时前
Playwright MCP:AI Agent 驱动 Web 自动化测试的架构与执行机制
前端·人工智能·架构
Jmyd01232 小时前
VR全景线上展会制作流程技术解析:全景采集、点云重建与Web端渲染优化实战
前端·javascript·vr·三维数字化