夜雨聆风学习资料网

ARTICLE · 1145701

盘点一个 Python Excel 数字转中文业务等级完整方案

盘点一个 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 自动化脚本,我一直觉得不要追求写得多复杂。

真正稳定的代码,往往就是几个转换函数,加上一点异常记录,把人工重复操作干掉。

相关学习资料