You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现Excel转JSON 同维度聚合求和适配Telegram机器人

问题概述
  • 现有.xlsx格式业务数据样例如下:
    Excel数据样例截图
  • 需将Excel转换为结构化JSON,供Telegram机器人使用:机器人按顺序询问用户设备品牌、设备名称、查询月份三个条件,匹配后返回对应设备单价、总金额。
  • 原有代码存在运行报错,且未实现核心聚合规则:相同设备名称、相同月份的重复记录,需要对device_price、device_summ字段求和合并。
原有代码问题排查
  • 行遍历范围错误:range(2, maxrows)会遗漏最后一行数据,openpyxl行号从1计数,正确遍历范围应为range(2, maxrows + 1)
  • 存在未定义变量:代码中引用了从未赋值的device_price_uah、device_summ_uah,运行时直接触发NameError
  • 月份处理逻辑硬编码:仅判断了2020年10月、11月两个月份,无法适配其他月份数据
  • 无聚合逻辑:以行号为存储key,相同设备、相同月份的重复记录不会合并
  • 输出结构不利于查询:以行号为key的字典结构,机器人查询时需要遍历所有键做匹配,效率低
修正后完整代码
from openpyxl import load_workbook
import json
from datetime import datetime

# 加载Excel文件,data_only=True读取单元格计算后的值,避免公式读取异常
wb = load_workbook('data.xlsx', data_only=True)
ws = wb.active
maxrows = ws.max_row
print(f"Excel文件总行数(含表头):{maxrows}")

# 聚合存储字典,使用(设备品牌, 设备名称, 月份标识)作为唯一键做聚合
aggregated_data = {}

# 遍历所有数据行(表头为第1行,从第2行开始遍历到最后一行)
for row_idx in range(2, maxrows + 1):
    # 读取单元格值,数值字段空值兜底为0
    device_name = ws[f'A{row_idx}'].value
    device_brand = ws[f'B{row_idx}'].value
    device_price_usd = ws[f'C{row_idx}'].value or 0
    device_summ_usd = ws[f'D{row_idx}'].value or 0
    month_cell_val = ws[f'E{row_idx}'].value

    # 跳过缺核心字段的空行/无效行
    if not all([device_name, device_brand, month_cell_val]):
        continue

    # 自动转换月份格式,生成类似oct_2020、nov_2020的标识,无需硬编码判断
    if isinstance(month_cell_val, datetime):
        date_obj = month_cell_val
    else:
        # 兼容字符串格式的日期值
        date_obj = datetime.strptime(str(month_cell_val).split()[0], "%Y-%m-%d")
    month_key = f"{date_obj.strftime('%b').lower()}_{date_obj.year}"

    # 生成聚合唯一键
    agg_key = (device_brand, device_name, month_key)

    if agg_key not in aggregated_data:
        # 键不存在则初始化记录
        aggregated_data[agg_key] = {
            "device_name": device_name,
            "device_brand": device_brand,
            "device_price_usd": float(device_price_usd),
            "device_summ_usd": float(device_summ_usd),
            "month": month_key
        }
    else:
        # 键已存在则累加金额字段,实现同设备同月份记录合并
        aggregated_data[agg_key]["device_price_usd"] += float(device_price_usd)
        aggregated_data[agg_key]["device_summ_usd"] += float(device_summ_usd)

# 转换为列表结构,方便Telegram机器人遍历查询
final_data = list(aggregated_data.values())

# 写入JSON文件,指定utf-8编码避免中文乱码
with open("data.json", "w", encoding="utf-8") as file:
    json.dump(final_data, file, indent=4, ensure_ascii=False)

print(f"数据处理完成,共生成{len(final_data)}条聚合后有效记录,已写入data.json")
使用说明
  • 代码默认读取同目录下的data.xlsx文件,运行后在同目录生成data.json结果文件
  • 月份格式自动识别转换,支持所有公历月份,无需手动添加判断分支
  • 自动对同品牌、同设备名、同月份的记录做金额累加,满足聚合要求
  • 最终输出的JSON为列表结构,机器人查询时可直接遍历匹配三个条件返回结果,参考查询逻辑:
# Telegram机器人查询逻辑示例
def get_matched_record(target_brand, target_name, target_month):
    for item in final_data:
        if item["device_brand"] == target_brand and item["device_name"] == target_name and item["month"] == target_month:
            return f"匹配结果:\n设备单价(USD):{item['device_price_usd']}\n总金额(USD):{item['device_summ_usd']}"
    return "未查询到符合条件的设备记录"

内容的提问来源于stack exchange,提问作者Nik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 14:42:17