如何用Python将多工作表Excel转换为指定嵌套JSON文件?
解决思路与实现代码
首先要明确:你想要的JSON格式不合法——JSON语法不允许在对象中直接嵌套无键的对象,也不能在数组里存放键值对(数组仅用于存储值集合,键值对需放在对象中)。先给你修正后的合法目标结构(两种可选):
结构一(紧凑键值对)
{ "A": { "P1": { "T1": "P1.com" }, "P2": { "T2": "P2.com", "T3": "P2.com" } }, "B": { "Q1": { "T1": "Q1.com" }, "Q2": { "T2": "Q2.com" } }, "C": { "R1": { "T1": "R1.com" }, "R2": { "T2": "R2.com" } } }
结构二(层级更清晰,推荐)
[ { "Name": "A", "Projects": [ { "Project": "P1", "Tasks": { "T1": "P1.com" } }, { "Project": "P2", "Tasks": { "T2": "P2.com", "T3": "P2.com" } } ] }, { "Name": "B", "Projects": [ { "Project": "Q1", "Tasks": { "T1": "Q1.com" } }, { "Project": "Q2", "Tasks": { "T2": "Q2.com" } } ] } ]
实现步骤与代码
假设你的Excel表头包含Name、Project,以及T1/T2/T3这类任务列,每行对应某Name下某Project的任务数据(空值代表该Project无此任务)。
代码实现(生成结构一)
import json import pandas as pd # 读取Excel文件 df = pd.read_excel(r'D:\example.xlsx', sheet_name='Sheet1') # 筛选所有以T开头的任务列 task_cols = [col for col in df.columns if col.startswith('T')] # 初始化最终结果字典 result = {} # 按Name分组处理 for name, name_group in df.groupby('Name'): project_dict = {} # 同一Name下再按Project分组 for project, proj_group in name_group.groupby('Project'): tasks = {} # 提取当前Project的有效任务数据(过滤空值) for col in task_cols: val = proj_group[col].dropna().iloc[0] if not proj_group[col].isna().all() else None if val is not None: tasks[col] = val project_dict[project] = tasks result[name] = project_dict # 导出为JSON文件 with open(r'D:\output.json', 'w', encoding='utf-8') as f: json.dump(result, f, indent=2, ensure_ascii=False)
若要生成结构二,替换结果构建部分即可
result = [] for name, name_group in df.groupby('Name'): projects_list = [] for project, proj_group in name_group.groupby('Project'): tasks = {} for col in task_cols: val = proj_group[col].dropna().iloc[0] if not proj_group[col].isna().all() else None if val is not None: tasks[col] = val projects_list.append({ "Project": project, "Tasks": tasks }) result.append({ "Name": name, "Projects": projects_list })
关键说明
groupby是pandas分组处理的核心方法,能快速将同Name/Project的数据归为一组;- 过滤空值是为了避免JSON中出现无效的
null值,若不需要可直接移除空值判断逻辑; json.dump的indent=2用于格式化JSON,提升可读性;ensure_ascii=False支持中文内容(若你的数据包含中文)。
内容的提问来源于stack exchange,提问作者Anoosha
相关产品推荐
相关产品推荐

