ARTICLE · 1145701
盘点一个 Python Excel 数字转中文业务等级完整方案
Excel 里有一类需求特别烦。
金额转中文、等级转中文、审批级别转中文,这些看起来都是“小功能”,但一旦进了业务系统,就会变成到处散落的小工具。
比如运营导出的表:
用户ID 消费等级
10001 1
10002 2
10003 3
10004 4
产品希望导出后变成:
用户ID 消费等级
10001 一级
10002 二级
10003 三级
10004 四级
很多人的第一反应是在 Excel 里写公式。
=IF(B2=1,"一级",IF(B2=2,"二级"...))
数据少的时候还能忍。
但我实际项目里更倾向于把这类规则放到 Python 里处理。
原因很简单,Excel 公式写多了以后,维护成本比代码还高。
今天就整理一个比较完整的方案:读取 Excel,识别数字等级,转换中文,再输出新的业务文件。
这里用 Python + openpyxl。
先看一个真实一点的数据。
假设业务部门每天给我们一个会员等级文件:
member_level.xlsx
用户编号 用户名称 等级
10001 张三 1
10002 李四 2
10003 王五 3
10004 赵六 5
规则:
1:普通会员 2:银卡会员 3:金卡会员 4:钻石会员 5:黑金会员
这里有一个坑。
很多人会直接:
level_map = {
1: "普通会员",
2: "银卡会员"
}
然后:
level_map[level]
线上很容易炸。
为什么?
Excel 里面读出来的数据类型不一定稳定。
有时候是:
1
有时候是:
"1"
甚至有人手工改成:
一级
所以业务转换代码不能只考虑正常情况。
我一般会单独抽一个转换函数。
代码不要写在 Excel 循环里面。
否则后面规则变化,改起来特别痛苦。
defconvert_level(value):
"""
业务等级转换
"""
level_dict = {
"1": "普通会员",
"2": "银卡会员",
"3": "金卡会员",
"4": "钻石会员",
"5": "黑金会员"
}
if value isNone:
return"未知等级"
key = str(value).strip()
return level_dict.get(key, "未知等级")
这里有个细节。
我没有直接判断:
if value == 1
而是统一转字符串。
因为 Excel 数据清洗场景里,类型问题非常常见。
接下来读取 Excel。
假设原文件:
member_level.xlsx
处理之后生成:
member_level_result.xlsx
代码如下:
from openpyxl import load_workbook
defprocess_excel(source_file, target_file):
workbook = load_workbook(source_file)
sheet = workbook.active
# 新增转换后的列
sheet.cell(row=1, column=4).value = "中文等级"
for row in range(2, sheet.max_row + 1):
level_value = sheet.cell(
row=row,
column=3
).value
chinese_level = convert_level(level_value)
sheet.cell(
row=row,
column=4
).value = chinese_level
workbook.save(target_file)
process_excel(
"member_level.xlsx",
"member_level_result.xlsx"
)
这种写法比较适合后台任务。
每天跑一次,把运营文件转换后丢出去。
不过实际项目里,我更关注异常数据。
比如:
用户编号 等级
10001 1
10002 2
10003 VIP
10004
10005 99
如果直接转换:
VIP -> 未知等级
空 -> 未知等级
99 -> 未知等级
表面没问题。
但是业务人员会问:
为什么这个用户没有等级?
所以一般我会把异常数据单独记录。
比如:
import logging
logging.basicConfig(
filename="level_convert.log",
level=logging.WARNING
)
defconvert_level(value):
level_dict = {
"1": "普通会员",
"2": "银卡会员",
"3": "金卡会员",
"4": "钻石会员",
"5": "黑金会员"
}
key = str(value).strip()
if key notin level_dict:
logging.warning(
"发现未知等级数据:%s",
value
)
return"未知等级"
return level_dict[key]
这样第二天运营反馈的时候,可以直接看日志。
不用重新打开十几个 Excel 找问题。
还有一种比较常见的需求:
数字转中文序号。
比如审批流程:
流程节点 顺序
提交 1
主管审批 2
经理审批 3
总监审批 4
导出希望:
提交 一
主管审批 二
经理审批 三
总监审批 四
这个和等级转换类似。
可以单独封装。
defnumber_to_chinese(num):
mapping = {
1: "一",
2: "二",
3: "三",
4: "四",
5: "五",
6: "六",
7: "七",
8: "八",
9: "九"
}
return mapping.get(
int(num),
"未知"
)
不要一开始就搞几十行中文数字算法。
业务系统里面,很多时候范围其实很小。
例如:
等级:
1-10
月份:
1-12
审批节点:
1-20
简单映射反而更稳定。
如果 Excel 数据量比较大,比如几十万行,我一般不会边读边保存。
因为 openpyxl 对大文件性能一般。
这种情况可以改成流式处理。
比如:
from openpyxl import load_workbook
wb = load_workbook(
"big_level.xlsx",
read_only=True
)
ws = wb.active
for row in ws.iter_rows(
values_only=True
):
user_id = row[0]
level = row[2]
result = convert_level(level)
print(
user_id,
result
)
先处理数据,再决定怎么写。
不要拿 Excel 当数据库用。
最后总结一下。
数字转中文这种需求,看起来简单,真正放进业务里,坑主要在几个地方:
第一,Excel 数据类型不稳定。
数字可能是:
1
"1"
" 一级 "
所以入口一定要清洗。
第二,转换规则不要散落。
不要十几个地方写:
if level == 1:
后面产品改等级,你会改到怀疑人生。
第三,异常数据要留痕。
业务系统最怕的不是报错,而是静默产生错误数据。
一个“未知等级”,如果没有日志,很可能几个月后才被发现。
这类 Excel 自动化脚本,我一直觉得不要追求写得多复杂。
真正稳定的代码,往往就是几个转换函数,加上一点异常记录,把人工重复操作干掉。