如何在Python中高效将YAML文件转换为Excel表格?
高效解析YAML并填充Excel模板的方案
问题说明
我不清楚如何高效解析YAML文件并将其转换为Excel文件。我尝试了如下代码,但认为可以更快还原Excel模板的样式:
for i,planche in enumerate (my_data["Culture par planche"]): #print(planche) for _planche in planche: print(planche[_planche][0]["surface"][0]["2"][0])
我的YAML文件内容示例(以Planche A为例,完整文件包含4个planche):
- Culture par planche : - Planche A: - surface: - "2": - 198 - Zones: - "1": - Rangs: - "1": - surface: - "2": - 33 - plantes: - Aubergine: - nombre: 21 - surface totale nécessaire: 15 - poids total: 42 - Plantation: - 5 - 6 - 7 - Récolte: - 7 - 8 - 9 - 10 - 1 - Betteraves: - nombre: 660 - surface totale nécessaire: 15 - poids total: 42 - Plantation: - 1 - 2 - 3 - 4 - Récolte: - 5 - 6 - 7 - 8 - 9 - Epinards: - nombre: 33 - surface totale nécessaire :3 - poids total :5 - Plantation: - 10 - Récolte: - 1 - 10 - 11 - 12 - Pois: - nombre: 13 - surface totale nécessaire: 3 - poids total: 4.5 - Plantation: - 2 - 3 - 4 - 5 - 6 - 7 - Récolte: - 3 - 4 - 5 - 6 - 7 - 8 - 9 - Blettes-poirées: - nombre: 60 - surface totale nécessaire: 15 - poids total: 120 - Plantation: - 1 - 2 - 3 - 4 - Récolte: - 1 - 2 - 3 - 4 - 5 - Navet: - nombre: 900 - surface totale nécessaire: 15 - poids total :30 - Plantation: - 12 - Récolte: - 1 - 2 - 3 - 4 - Fèves: - nombre: 300 - surface totale nécessaire: 15 - poids total: 11.25 - Plantation: - 10 - 11 - 12 - Récolte: - 4 - 5 - "2": - surface: - "2": - 33 - plantes: - Fraise: - nombre: 132 - surface totale nécessaire: 33 - poids total: 105 - Plantation: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - Récolte: - 5 - 6 - 7 - 8 - 9 - 10 - Ail: - nombre: 200 - surface totale nécessaire: 10 - poids total: 20 - Plantation: - 10 - 11 - 12 - Récolte: - 5 - 6 - "3": - surface: - "2": - 33 - plantes: - Piments: - nombre: 40 - surface totale nécessaire: 10 - poids total: 6 - Plantation: - 3 - 4 - Récolte: - 6 - 7 - 8 - 9 - 10 - Poivrons: - nombre: 30 - surface totale nécessaire: 10 - poids total: 50 - Plantation: - 3 - 4 - Récolte: - 6 - 10 - Haricots fil et rame: - nombre: 25 - surface totale nécessaire: 10 - poids total: 17 - Plantation: - 4 - 5 - 6 - Récolte: - 6 - 9 - Mesclun: - nombre: 75 - surface totale nécessaire: 3 - poids total: 3 - Plantation: - 3 - 4 - 5 - 6 - 7 - Récolte: - 5 - 6 - 7 - 8 - 9 - 10 - Navet: - nombre: 1200 - surface totale nécessaire: 20 - poids total: 40 - Plantation: - 11 - 12 - Récolte: - 1 - 2 - 3 - 4 - 5 - 11 - 12 - Radis: - nombre: 7785 - surface totale nécessaire: 13 - poids total: 39 - Plantation: - 1 - 2 - 11 - 12 - Récolte: - 1 - 2 - 3 - 4 - 5 - 11 - 12 - "4": - surface: - "2": - 33 - plantes: - Tomates: - nombre: 100 - surface totale nécessaire: 20 - poids total: 220 - Plantation: - 3 - 4 - 5 - Récolte: - 6 - 7 - 8 - 9 - 10 - 11 - Carottes: - nombre: 910 - surface totale nécessaire: 13 - poids total: 39 - Plantation: - 2 - 3 - 4 - 5 - 6 - 7 - Récolte: - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - Oignons: - nombre: 440 - surface totale nécessaire: 20 - poids total: 60 - Plantation: - 1 - 2 - 11 - 12 - Récolte: - 1 - 2 - 3 - 4 - 5 - "5": - surface: - "2": - 33 - plantes: - Tomates cerises: - nombre: 100 - surface totale nécessaire: 20 - poids total: 240 - Plantation: - 3 - 4 - 5 - Récolte: - 6 - 7 - 8 - 9 - 10 - Concombre: - nombre: 13 - plans: 13 - INFO - 1 plante == 1 plan produit N concombres - VOIR - rendement d'un plan de concombre - poids total: 195 - Plantation: - 3 - 4 - 5 - Récolte: - 5 - 6 - 7 - 8 - 9 - Roquette: - nombre: 390 - surface totale nécessaire: 13 - poids total: 13 - Plantation: - 8 - 9 - 10 - Récolte: - 3 - 4 - 10 - 11 - Pois: null - nombre: 85 - surface totale nécessaire: 20 - poids total: 30 - Plantation: - 9 - 10 - Récolte: - 10 - 11 - 12 - "6": - surface: - "2": - 33 - plantes: - Fraise: - nombre: 132 - surface totale nécessaire: 33 - poids total: 105 - Plantation: - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - Récolte: - 5 - 6 - 7 - 8 - 9 - 10 - Ail: - nombre: 200 - surface totale nécessaire: 10 - poids total: 20 - Plantation: - 10 - 11 - 12 - Récolte: - 5 - 6
Excel模板样式说明:需按地块(Planche)、区域(Zone)、行(Rang)分类,展示每种作物的基础信息(数量、所需面积、总重量),并在对应月份列标记种植(Plantation)和收获(Récolte)时间(整数代表月份)。
解决方案
1. 安装依赖
先安装所需的Python库:
pip install pyyaml openpyxl
2. 完整代码实现
import yaml from openpyxl import load_workbook def parse_yaml(yaml_path): """解析YAML文件,提取结构化数据""" with open(yaml_path, 'r', encoding='utf-8') as f: data = yaml.safe_load(f) # 处理YAML顶层的列表结构,提取地块数据 culture_data = data[1] parsed_data = [] for planche_name, planche_info in culture_data.items(): # 遍历每个区域 zones = planche_info[1]['Zones'][0] for zone_num, zone_info in zones.items(): # 遍历每个行 rangs = zone_info[0]['Rangs'] for rang_num, rang_info in rangs.items(): # 遍历每个作物 plantes = rang_info[1]['plantes'] for plante in plantes: for plante_name, plante_details in plante.items(): # 跳过空值作物 if plante_details is None: continue # 提取作物核心信息 parsed_data.append({ '地块': planche_name, '区域': zone_num, '行': rang_num, '作物名称': plante_name, '数量': plante_details.get('nombre'), '所需面积': plante_details.get('surface totale nécessaire'), '总重量': plante_details.get('poids total'), '种植月份': plante_details.get('Plantation', []), '收获月份': plante_details.get('Récolte', []) }) return parsed_data def fill_excel(template_path, parsed_data, output_path): """将解析后的数据填充到Excel模板中""" wb = load_workbook(template_path) ws = wb.active row_idx = 2 # 假设模板第1行是表头 for item in parsed_data: # 写入基础信息列 ws.cell(row=row_idx, column=1, value=item['地块']) ws.cell(row=row_idx, column=2, value=item['区域']) ws.cell(row=row_idx, column=3, value=item['行']) ws.cell(row=row_idx, column=4, value=item['作物名称']) ws.cell(row=row_idx, column=5, value=item['数量']) ws.cell(row=row_idx, column=6, value=item['所需面积']) ws.cell(row=row_idx, column=7, value=item['总重量']) # 标记种植月份(假设第8列对应1月,依次类推) for month in item['种植月份']: col_idx = 7 + int(month) ws.cell(row=row_idx, column=col_idx, value='√') # 标记收获月份(假设第20列对应1月,依次类推,需根据实际模板调整) for month in item['收获月份']: col_idx = 19 + int(month) ws.cell(row=row_idx, column=col_idx, value='√') row_idx += 1 wb.save(output_path) if __name__ == '__main__': # 替换为你的文件路径 yaml_file = 'culture.yaml' template_file = 'template.xlsx' output_file = '填充完成的种植表.xlsx' data = parse_yaml(yaml_file) fill_excel(template_file, data, output_file) print(f"文件已生成:{output_file}")
3. 注意事项
- 代码中的列索引需要根据你的实际Excel模板调整,比如种植/收获月份对应的起始列
- 若需要还原模板的样式(如单元格颜色、字体),可使用
openpyxl.styles模块扩展代码 - 已处理YAML中的空值作物(如
Pois: null),避免解析报错
内容的提问来源于stack exchange,提问作者Garbez François
相关产品推荐
相关产品推荐

