Excel 导入原文保留与内联排名配置问题复盘
1. 分享主题
主题:不要让导入解析"偷偷替业务做决定"------从"零发案被转成 0"看数据原文保留、类型识别与排名配置设计
这次分享围绕一个看似很小的问题展开:
Excel 预览里用户看到的是"零发案",但导入后系统把它变成了数字
0,导致内联页、榜单、柱图、排名全部按0处理。
这个问题表面上是一个字段解析问题,本质上是:
系统在导入阶段过早地把"展示值、原始值、计算值、排序规则"混在了一起,导致业务含义丢失。
2. 问题背景
在某个 Excel 导入场景中,用户上传的数据里存在非标准数字内容,例如:
零发案-无- 空单元格
- 正常数字,如
2.01
Excel 预览阶段,系统显示是正确的:
| 位置 | 用户看到的内容 |
|---|---|
| Excel / 查看预览 | 零发案 |
但是导入完成后,明细数据被解析成了:
| 位置 | 实际存储/显示 |
|---|---|
| 导入后的明细 | score = 0 |
| 内联页「原始值」 | 显示 0 |
| 内联页「值类型」 | 显示「数字」 |
| 榜单 / 排名 / 柱图 | 按数字 0 参与计算 |
最终用户会产生疑问:
我 Excel 里填的是"零发案",为什么系统里变成了 0?
3. 这不是简单的"显示错了"
这个问题不能只理解为"页面显示错了"。
真正的问题链路是:
Excel 单元格:零发案
导入解析 parseScoreMaybe
被静默转成 score = 0
明细表原文丢失
看板矩阵 values 只拿到 0
内联页显示 0
类型识别为数字
排名/柱图按 0 计算
核心问题是:
用户输入的是业务表达,系统却在导入阶段把它强行转成了数字结果。
一旦原文丢失,后续页面再怎么调整,都很难恢复真实业务含义。
4. 用大白话理解这个问题
可以把系统理解成一个"抄表的人"。
用户 Excel 里写的是:
零发案
系统导入时却抄成了:
0
后面的页面、图表、排名都只看到了 0,自然会认为用户填的是数字 0。
正确做法应该是:
用户写什么,系统先原样记下来;
如果能识别成数字,再额外生成一个可计算值;
如果不能识别成数字,不要擅自当成 0;
排名、图表、靠前靠后规则,交给看板配置决定。
5. 核心设计原则
这类问题后续处理时,要坚持四个原则。
5.1 原文不能丢
Excel 里用户填了什么,系统必须能追溯。
例如:
| Excel 原文 | 系统应该保留 |
|---|---|
| 零发案 | rawValue = "零发案" |
| 2.01 | rawValue = "2.01",同时 score = 2.01 |
| - | rawValue = "-",score = null |
| 空 | rawValue = "",score = null |
不要只存一个 score。
5.2 数字值和展示值要分开
系统里至少要区分两类值:
| 类型 | 作用 |
|---|---|
| 原始值 / 展示值 | 用于页面展示、用户核对、问题追溯 |
| 数字值 / 计算值 | 用于求和、排名、柱图、得分计算 |
不能把展示值直接等同于计算值。
5.3 解析函数不能静默兜底成 0
对于非数字内容,不应该默认 return 0。
错误做法:
text
零发案 → 0
- → 0
空 → 0
无 → 0
正确做法:
text
零发案 → rawValue = "零发案", score = null
- → rawValue = "-", score = null
空 → rawValue = "", score = null
2.01 → rawValue = "2.01", score = 2.01
5.4 排名由配置决定,不由导入决定
导入阶段只负责:
- 读取原文
- 判断是否可转数字
- 保存原始值和计算值
导入阶段不应该决定:
- 这个值是否参与排名
- 特殊值靠前还是靠后
- 数字越高越靠前还是越低越靠前
- 人工指定项是否优先置顶
这些应该交给看板或内联页配置。
6. 三个改法的业务解释
这次沟通中,总结出三条改法。
6.1 方案一:明细层增加 rawValue / displayValue
一句话解释:
每条导入明细,除了存可计算的
score,还要单独存用户 Excel 单元格里的原始内容。
现在的问题
当前可能只存了:
| 字段 | 值 |
|---|---|
| objectName | 刑侦 |
| indicator | 未成年人失联 |
| score | 0 |
这样已经看不出来用户原来填的是:
零发案
改后应该是
| 字段 | 值 |
|---|---|
| objectName | 刑侦 |
| indicator | 未成年人失联 |
| rawValue | 零发案 |
| score | null |
| valueType | text / special |
如果是正常数字:
| 字段 | 值 |
|---|---|
| rawValue | 2.01 |
| score | 2.01 |
| valueType | number |
页面怎么用
| 页面位置 | 使用规则 |
|---|---|
| 内联页「原始值」 | 优先显示 rawValue |
| 内联页「值类型」 | 根据 score 是否为有效数字判断 |
| 排名 / 柱图 | 只对有效数字参与计算,特殊值按配置处理 |
这条方案解决什么
解决的是:
明细层能不能看见用户原来填了什么。
6.2 方案二:buildIndicatorMatrix.values 支持 string | number
一句话解释:
看板用的「地区 × 指标」矩阵里,也不能只存数字,要允许存字符串原文。
现在的问题
当前矩阵可能是:
| 地区 | 值 |
|---|---|
| 县局 | 0.01 |
| 刑侦 | 0 |
| 治安 | 2.01 |
这里的 刑侦 = 0 是错的,因为 Excel 原文是:
零发案
改后应该是
| 地区 | 值 |
|---|---|
| 县局 | 0.01 |
| 刑侦 | 零发案 |
| 治安 | 2.01 |
也就是:
text
values = {
"县局": 0.01,
"刑侦": "零发案",
"治安": 2.01
}
内联页怎么用
内联页读取矩阵时:
| 数据 | 页面表现 |
|---|---|
0.01 |
数字 |
"零发案" |
文字 / 特殊值 |
2.01 |
数字 |
柱图怎么用
柱图不能再把 "零发案" 当成 0 画一根矮柱。
而应该根据配置处理:
| 配置 | 处理方式 |
|---|---|
| 特殊值不参与图表 | 不画柱 |
| 特殊值置灰展示 | 展示为灰态标签 |
| 特殊值靠后 | 排在后面 |
| 特殊值靠前 | 排在前面,但不按高度计算 |
| 人工指定置顶 | 可强制放到第一位或靠前位置 |
这条方案解决什么
解决的是:
看板最终展示、排序、图表使用的数据,不能在矩阵构建阶段再次丢失原文。
6.3 方案三:parseScoreMaybe 不要对汉字静默 return 0
一句话解释:
解析函数看不懂时,不要假装自己看懂了,更不要默认转成 0。
当前错误逻辑
text
空 → 0
- → 0
无 → 0
零发案 → 0
2.01 → 2.01
这会导致:
| 原始内容 | 系统结果 | 问题 |
|---|---|---|
| 空 | 0 | 空值被当成 0 |
| - | 0 | 特殊符号被当成 0 |
| 零发案 | 0 | 文本被当成 0 |
| 2.01 | 2.01 | 正常 |
改后逻辑
text
空 → score = null, rawValue = ""
- → score = null, rawValue = "-"
无 → score = null, rawValue = "无"
零发案 → score = null, rawValue = "零发案"
2.01 → score = 2.01, rawValue = "2.01"
这条方案解决什么
解决的是:
导入瞬间不要把非数字文本错误压成数字 0。
这是最前面的止血点。
7. 三个方案之间的关系
这三个方案不是互斥关系,而是一个完整链路。
| 方案 | 改在哪里 | 解决的问题 | 大白话 |
|---|---|---|---|
| 方案三 | 导入解析函数 | 不要把汉字变成 0 | 导入时别乱猜 |
| 方案一 | 导入明细表 | 把用户原文存下来 | 用户写什么就记什么 |
| 方案二 | 看板矩阵 values | 看板展示和排序也保留原文 | 中间加工别再丢一次 |
推荐落地顺序:
渲染错误: Mermaid 渲染失败: Parse error on line 3: ...矩阵 values 支持 string | number] C --> -----------------------^ Expecting 'SQE', 'TAGEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'PIPE'
8. 和排序配置的关系
这次问题不是单纯的"零发案显示问题",还牵涉到内联页排名规则。
8.1 数字排序需要配置方向
对于纯数字指标,用户可能有两种业务含义:
| 业务含义 | 排序方向 |
|---|---|
| 得分越高越好 | 数字越大越靠前 |
| 问题越少越好 | 数字越小越靠前 |
所以配置页需要支持:
- 数字越高越靠前
- 数字越低越靠前
不能默认所有数字都是越高越好。
8.2 特殊值需要配置处理方式
对于 零发案、无、- 这类内容,需要配置:
- 是否参与排序
- 是否置灰展示
- 靠前还是靠后
- 是否允许人工指定位置
8.3 人工指定"靠前"不等于"第一名"
之前还有一个场景:
某个对象比如"高桥",当前在榜单下方。用户设置它"靠前"后,它只是排到了第三位,但用户希望它排第一。
这说明配置里要区分:
| 配置能力 | 含义 |
|---|---|
| 靠前 | 放在普通排序结果前面,但多个靠前项之间仍按规则排序 |
| 指定第一 | 强制放到第一位 |
| 指定名次 | 允许配置具体排名,如第 1、第 2、第 3 |
| 置顶优先级 | 多个置顶项按优先级排序 |
也就是说:
"靠前"是一种优先级增强,不一定等于"固定第一"。
如果业务明确要让某一项变成第一位,就需要增加更明确的配置能力,例如:
text
人工排序优先级:
1. 强制第 1 名
2. 强制第 2 名
3. 靠前展示
4. 按系统规则排序
5. 靠后展示
9. 推荐的最终设计口径
9.1 导入阶段
导入阶段只做三件事:
- 读取 Excel 原始单元格内容
- 判断是否为有效数字
- 同时保存原始值和数字值
导入阶段不做:
- 不决定排名
- 不决定特殊值靠前靠后
- 不把文本强行转成 0
- 不把空值、横杠、汉字混为一类
9.2 明细层
明细层建议字段:
| 字段 | 含义 | 示例 |
|---|---|---|
| objectName | 对象名称 | 刑侦 |
| indicatorKey | 指标 key | minor_lost |
| indicatorName | 指标名称 | 未成年人失联 |
| rawValue | Excel 原始值 | 零发案 |
| displayValue | 页面展示值 | 零发案 |
| score | 数字值 | null / 2.01 |
| valueType | 值类型 | number / text / empty / special |
| parseStatus | 解析状态 | success / non_numeric / empty |
| importBatchId | 导入批次 | batch_20260520 |
9.3 看板矩阵层
矩阵 values 建议支持:
ts
type MatrixValue = string | number | null;
示例:
ts
values = {
"县局": 0.01,
"刑侦": "零发案",
"治安": 2.01,
"交警": null
}
9.4 内联页展示
内联页建议展示:
| 列名 | 展示逻辑 |
|---|---|
| 对象 | 地区 / 单位 / 部门 |
| 原始值 | 优先展示 rawValue / displayValue |
| 值类型 | 数字 / 文本 / 空值 / 特殊值 |
| 排序状态 | 参与排序 / 不参与排序 / 人工靠前 / 人工置顶 |
| 图表状态 | 正常画柱 / 不画柱 / 置灰 |
9.5 排名配置
排名配置建议包含:
| 配置项 | 说明 |
|---|---|
| 数字排序方向 | 越高越靠前 / 越低越靠前 |
| 非数字值处理 | 不参与排序 / 靠前 / 靠后 / 置灰 |
| 空值处理 | 不参与排序 / 靠后 |
| 人工排序 | 靠前 / 靠后 / 指定名次 / 强制第一 |
| 冲突处理 | 多个人工指定时按优先级或配置顺序处理 |
10. 产品经理需要关注的关键点
这类问题,产品经理不能只写:
修复"零发案"显示问题。
这样研发很容易只改页面显示,底层问题仍然存在。
应该明确写成:
导入解析、明细存储、看板矩阵、内联页展示、排名配置、柱图展示需要形成完整链路,确保 Excel 原文不丢失,非数字文本不被静默转换为 0。
产品经理要重点补充以下内容:
10.1 明确字段口径
必须说明:
- 什么是原始值
- 什么是展示值
- 什么是数字值
- 什么是特殊值
- 什么是空值
10.2 明确解析规则
必须说明:
| 输入 | rawValue | score | valueType |
|---|---|---|---|
| 2.01 | 2.01 | 2.01 | number |
| 零发案 | 零发案 | null | text/special |
| - | - | null | special |
| 空 | 空 | null | empty |
| 无 | 无 | null | special |
10.3 明确展示优先级
比如:
text
内联页原始值显示优先级:
displayValue > rawValue > score > 空
10.4 明确排序规则
包括:
- 数字值怎么排序
- 文本值怎么排序
- 空值怎么排序
- 人工靠前怎么处理
- 人工指定第一怎么处理
- 多个特殊规则冲突时谁优先
10.5 明确图表规则
包括:
- 非数字是否画柱
- 空值是否画柱
- 特殊值是否置灰
- 是否显示标签
- 排序和柱图是否共用同一套规则
11. 可以直接给研发的需求描述
下面这段可以作为研发沟通口径:
当前问题不是 Excel 预览错误,而是导入解析和看板矩阵构建过程中,把非数字文本"零发案"静默转换成了
score = 0,导致原文丢失。后续内联页、榜单、柱图、排名都基于错误的 0 进行展示和计算。需要调整为:导入时保留单元格原始值
rawValue/displayValue;只有能明确识别为数字时才写入score;非数字文本不允许默认转 0。内联页「原始值」优先展示原文,值类型根据score是否为有效数字判断。看板矩阵values需要支持string | number | null,避免中间构建时再次丢失原文。最终排名和图表处理由看板配置规则决定,而不是导入阶段擅自把文本转成 0。
12. 验收标准
12.1 原文保留验收
| 测试输入 | 预期结果 |
|---|---|
| Excel 填"零发案" | 内联页原始值显示"零发案" |
| Excel 填"2.01" | 内联页原始值显示"2.01",类型为数字 |
| Excel 填"-" | 内联页原始值显示"-",类型为特殊值 |
| Excel 空单元格 | 内联页显示为空,类型为空值 |
| Excel 填"无" | 内联页显示"无",类型为特殊值 |
12.2 解析验收
| 输入 | score |
|---|---|
| 2.01 | 2.01 |
| 零发案 | null |
| - | null |
| 空 | null |
| 无 | null |
重点验收:
任何非数字文本都不能被静默转换成 0。
12.3 排名验收
| 场景 | 预期 |
|---|---|
| 配置数字越高越靠前 | 2.01 排在 0.01 前 |
| 配置数字越低越靠前 | 0.01 排在 2.01 前 |
| 配置特殊值不参与排序 | "零发案"不参与数字排名 |
| 配置特殊值靠后 | "零发案"排到数字项后面 |
| 配置特殊值靠前 | "零发案"排到数字项前面 |
| 配置某对象强制第一 | 该对象必须排在第一位 |
12.4 图表验收
| 场景 | 预期 |
|---|---|
| 数字值 | 正常画柱 |
| 零发案 | 不按 0 画柱 |
| 特殊值置灰 | 显示特殊标签或灰态 |
| 空值 | 不画柱或按配置展示 |
| 排序改变 | 图表顺序同步变化 |
13. 常见误区
误区一:只改页面显示
只把页面上的 0 替换成 零发案 是不够的。
因为底层数据仍然是错的,排名和图表还是会错。
误区二:认为"零发案"等于 0
业务上,"零发案"可能表示一种描述性结论,不一定等于数字 0。
即使它语义上接近"0 起案件",也不能在导入阶段擅自替用户转换。
是否转成数字,应该由明确规则决定。
误区三:所有非数字都不重要
非数字可能承载重要业务含义,例如:
- 零发案
- 未发生
- 无数据
- 暂未统计
- 不适用
-
这些都不能简单归为 0。
误区四:靠前就是第一
"靠前"只是排序优先级,不一定是固定第一名。
如果用户要第一名,就要提供"指定第一"或"指定名次"的配置。
14. 可复用的方法论
这类问题可以沉淀为一个通用判断框架:
14.1 先问四个问题
- 用户原始输入是什么?
- 系统存储时有没有改变它?
- 页面展示用的是原文还是计算值?
- 排名 / 图表 / 统计是由谁决定的?
14.2 再拆四类值
| 值类型 | 说明 |
|---|---|
| rawValue | 用户原始输入 |
| displayValue | 页面展示值 |
| score / numericValue | 计算值 |
| sortValue | 排序值 |
不要把这四类值混成一个字段。
14.3 最后明确三类规则
| 规则 | 示例 |
|---|---|
| 解析规则 | 什么能转数字,什么不能转 |
| 展示规则 | 原始值怎么显示,类型怎么标 |
| 排序规则 | 数字、文本、空值、人工置顶怎么排 |
15. 内部宣讲提纲
第一部分:问题引入
可以这样开场:
今天分享一个看起来很小、但很典型的数据导入问题:Excel 里用户填的是"零发案",系统导入后却变成了 0。这个问题不仅影响显示,还影响后面的排名、柱图和客户对系统可信度的判断。
第二部分:讲清楚现象
用一张表说明:
| 环节 | 现象 |
|---|---|
| Excel 预览 | 零发案 |
| 导入明细 | 0 |
| 内联页 | 0 + 数字 |
| 排名 | 按 0 排 |
| 柱图 | 按 0 画 |
第三部分:讲清楚根因
根因不是页面,而是:
导入解析阶段把非数字文本静默转换成了 0,导致原文丢失。
第四部分:讲三个方案
parseScoreMaybe不要静默转 0- 明细层增加
rawValue / displayValue - 看板矩阵
values支持string | number | null
第五部分:讲配置边界
重点说明:
排名怎么排,不应该由导入决定,而应该由看板配置决定。
包括:
- 数字越高越靠前
- 数字越低越靠前
- 特殊值靠前 / 靠后 / 不参与
- 人工指定第一 / 指定名次
第六部分:沉淀方法论
最后总结成一句话:
导入负责还原事实,配置负责表达业务规则,展示负责让用户看懂,计算负责在明确规则下执行。
16. 一句话总结
这次问题的本质不是"零发案显示成 0"这么简单,而是:
系统在导入阶段过早做了业务判断,把用户原始表达强行转换成数字,导致原文丢失、类型误判、排名错误、图表失真。
后续设计要坚持:
原文要保留,数字要单独算,特殊值要有类型,排序要靠配置。
17. 后续建议
建议把这次问题沉淀成团队通用规范:
17.1 Excel 导入规范
- 所有导入字段默认保留原始值
- 非数字文本不得静默转 0
- 空值、特殊值、文本值、数字值必须区分
- 导入结果页要展示解析状态
17.2 看板指标规范
- 指标值要区分展示值和计算值
- 矩阵数据支持
string | number | null - 图表只使用明确的数字值
- 特殊值处理必须可配置
17.3 排名配置规范
- 排序方向必须可配置
- 特殊值处理必须可配置
- 人工置顶和人工靠前要区分
- 多条排序规则要有优先级
18. 最终给团队的关键提醒
以后遇到类似问题,不要只问:
页面为什么显示错了?
而要继续追问:
- Excel 原始值是什么?
- 导入后存成了什么?
- 原文有没有丢?
- 展示值和计算值是不是混了?
- 排名规则是系统默认的,还是用户配置的?
- 图表是否把特殊值当成了数字?
- 有没有静默兜底成 0 的逻辑?
只有这样,才能避免"页面看起来修好了,实际业务规则还是错的"。