Openpyxl按Boat ID分组写入对应已有工作簿问题求解
源数据结构
源表boats.xlsx包含如下字段:
| Boat ID | Emp ID | Emp Name | Start Date | Manager |
|---|---|---|---|---|
| 1 | 16044 | Derrick | ASAP | Anthony |
| 1 | 16045 | John | ASAP | Anthony |
| 1 | 16046 | Bill | ASAP | Anthony |
| 1 | 16047 | Joe | ASAP | Anthony |
| 2 | 16048 | Justin | ASAP | Jacob |
| 2 | 16049 | Sandy | ASAP | Jacob |
| 2 | 16050 | Omar | ASAP | Jacob |
| 3 | 16051 | Michael | ASAP | Nathan |
| 3 | 16052 | Bill | ASAP | Nathan |
需求拆解
- 按
Boat ID对所有数据行分组,提取每行Boat ID右侧的所有列数据 - 每个唯一
Boat ID对应本地一个已存在的、列头与源表一致的Excel工作簿 - 提取的分组数据从对应工作簿的A2单元格开始写入(保留工作簿原有表头)
原有代码问题
原代码逻辑是新建一个汇总工作簿,为每个Boat ID创建独立工作表写入数据,和需求不符,存在两个核心问题:
- 读取源表时没有跳过表头行,把列头也存入了分组字典
- 没有匹配打开本地已存在的对应Boat ID工作簿,而是新建工作表写入
修改后代码
提前确认:所有Boat ID对应的目标工作簿和源文件boats.xlsx放在同一目录,且目标文件第一行已经预置好和源表一致的列头。代码默认目标文件以Boat ID直接命名,比如Boat ID为1对应1.xlsx,如果你的命名规则不同,修改代码里的路径拼接部分即可。
import os import openpyxl # 读取源数据 source_wb = openpyxl.load_workbook("boats.xlsx", read_only=True, data_only=True) source_ws = source_wb.active boat_data_map = {} # 从第2行开始遍历(跳过第1行表头) for row in source_ws.iter_rows(min_row=2, values_only=True): boat_id = row[0] # 截取Boat ID右侧的所有字段 target_row_data = row[1:] if boat_id not in boat_data_map: boat_data_map[boat_id] = [] boat_data_map[boat_id].append(target_row_data) source_wb.close() # 逐组写入对应目标工作簿 for boat_id, rows in boat_data_map.items(): # 替换为你实际的目标文件命名规则 target_file = f"{boat_id}.xlsx" # 校验文件是否存在,不存在则跳过 if not os.path.exists(target_file): print(f"跳过Boat ID {boat_id}:未找到对应文件{target_file}") continue # 打开已有工作簿 target_wb = openpyxl.load_workbook(target_file) # 默认写活动工作表,需要指定工作表就改成 target_wb["工作表名"] target_ws = target_wb.active # 从A2(第2行第1列)开始写入 write_start_row = 2 for r_idx, row_content in enumerate(rows, start=write_start_row): for c_idx, val in enumerate(row_content, start=1): target_ws.cell(row=r_idx, column=c_idx, value=val) # 保存并关闭 target_wb.save(target_file) target_wb.close() print(f"Boat ID {boat_id} 数据写入完成")
可选调整说明
- 如果需要把数据追加到目标工作簿已有数据的末尾,而不是固定从A2开始覆盖,把
write_start_row = 2改成write_start_row = target_ws.max_row + 1 - 如果目标工作簿存放在其他路径,把
target_file改成完整绝对路径即可,比如f"C:/数据/船号{boat_id}.xlsx" - 如果需要保留单元格格式,写入时可以额外复制样式,基础数据写入用上述代码即可满足需求
内容的提问来源于stack exchange,提问作者diddlyd43
相关产品推荐
相关产品推荐

