Python脚本无法将Excel列数据复制到主工作簿,求排查方向
Excel数据复制脚本无报错但未生效的排查方向
问题描述
我要实现一个自动化流程,把Excel工作表里的列数据复制到已有的主Excel文件对应工作表中,已经在Python代码里加了映射逻辑,还希望脚本在Excel文件放入项目目录时触发(这部分暂时不重要)。现在运行脚本没有报错,但数据根本没复制到主Excel文件里,找不到问题出在哪,求指点排查方向。
代码实现
import openpyxl import os from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler # 设置文件名与对应工作表/列的映射关系 file_mappings = { "Adams_Survey.xlsx": [ {"source_worksheet": "1 General County Information", "target_worksheet": "1 General County Information", "column": "B"}, {"source_worksheet": "2 Special Events-Exposure", "target_worksheet": "2 Special Events-Exposure", "column": "B"}, {"source_worksheet": "3 Fair", "target_worksheet": "3 Fair", "column": "B"}, {"source_worksheet": "4 Utilities", "target_worksheet": "4 Utilities", "column": "B"}, {"source_worksheet": "5 Public Works", "target_worksheet": "5 Public Works", "column": "B"}, {"source_worksheet": "6 Solid Waste - Facilities", "target_worksheet": "6 Solid Waste - Facilities", "column": "B"}, {"source_worksheet": "7 Parks and Recreation", "target_worksheet": "7 Parks and Recreation", "column": "B"}, {"source_worksheet": "8 Health Department", "target_worksheet": "8 Health Department", "column": "B"}, {"source_worksheet": "9 Law Enforcement", "target_worksheet": "9 Law Enforcement", "column": "B"}, {"source_worksheet": "10 Human Resources - Employment", "target_worksheet": "10 Human Resources - Employment", "column": "B"}, {"source_worksheet": "11 Cyber Security", "target_worksheet": "11 Cyber Security", "column": "B"}, {"source_worksheet": "12 Emergency Management", "target_worksheet": "12 Emergency Management", "column": "B"} ], # 可添加更多文件映射 } # 目标主Excel文件名 existing_workbook_name = "SurveySelfAssess.xlsx" # 加载主工作簿 existing_wb = openpyxl.load_workbook(existing_workbook_name) class FileHandler(FileSystemEventHandler): def on_created(self, event): if event.is_directory: return elif event.src_path.endswith('.xlsx'): file = os.path.basename(event.src_path) if file.startswith('~$') or file.startswith('$'): return # 检查当前文件是否有映射配置 if file in file_mappings: mappings = file_mappings[file] # 加载源工作簿 wb = openpyxl.load_workbook(file) for mapping in mappings: source_worksheet_name = mapping["source_worksheet"] target_worksheet_name = mapping["target_worksheet"] column_letter = mapping["column"] # 获取源工作表 ws = wb[source_worksheet_name] # 根据首行内容定位要复制的列 col_to_copy = None for col in range(1, ws.max_column + 1): if ws.cell(row=1, column=col).value == "Column to Copy": col_to_copy = col break # 找到目标列后执行复制 if col_to_copy: # 获取目标工作表 existing_ws = existing_wb[target_worksheet_name] # 将目标列字母转换为列号 existing_column_number = openpyxl.utils.column_index_from_string(column_letter) # 逐行复制列数据 for row in range(1, ws.max_row + 1): existing_ws.cell(row=row, column=existing_column_number, value=ws.cell(row=row, column=col_to_copy).value) print(f"已从'{file}'的'{source_worksheet_name}'工作表复制'Column to Copy'列,粘贴到'{existing_workbook_name}'的'{target_worksheet_name}'工作表的{column_letter}列") else: print(f"在'{file}'的'{source_worksheet_name}'工作表中未找到'Column to Copy'列") else: print(f"未找到'{file}'的映射配置") if __name__ == "__main__": event_handler = FileHandler() observer = Observer() observer.schedule(event_handler, path='.', recursive=False) observer.start() try: while True: pass except KeyboardInterrupt: observer.stop() observer.join() # 保存主工作簿 existing_wb.save(existing_workbook_name)
排查方向
- 保存时机错误:你把
existing_wb.save()放在了主程序循环之外,只有按下Ctrl+C终止脚本时才会执行保存。这意味着脚本运行期间的所有修改都只存在于内存中,根本没写入磁盘。解决方法是把保存操作移到on_created方法内,比如每次处理完一个文件或一个工作表后立即执行existing_wb.save(existing_workbook_name)。 - 文件未完全写入就触发事件:watchdog的
on_created事件会在文件开始创建时就触发,此时文件可能还没完全写入磁盘,导致加载的源文件不完整。可以在处理文件前添加延迟,比如导入time模块后,在wb = openpyxl.load_workbook(file)前加time.sleep(2),等文件完全写入后再处理。 - 列匹配条件不成立:你通过首行值等于"Column to Copy"定位目标列,如果源文件首行的这个值存在大小写差异、空格或隐藏字符,会导致
col_to_copy为None,跳过复制逻辑。可以在列循环中添加打印,输出首行所有单元格的实际值,确认是否匹配:for col in range(1, ws.max_column + 1): cell_value = ws.cell(row=1, column=col).value print(f"首行列{col}的值: {repr(cell_value)}") # 用repr查看原始值 if cell_value == "Column to Copy": col_to_copy = col break - 工作表名称不匹配:openpyxl对工作表名称大小写敏感,检查源文件和主文件中的工作表名称是否与
file_mappings中的配置完全一致,包括空格、标点符号。 - 主文件被锁定:如果主文件
SurveySelfAssess.xlsx在脚本运行时被Excel或其他程序打开,会导致保存失败,但openpyxl不会抛出明显错误。确保脚本运行时主文件处于关闭状态。 - 添加关键日志:在
on_created方法开头、进入映射判断、找到目标列等关键位置添加打印语句,确认脚本实际执行到了哪一步,比如:def on_created(self, event): print(f"检测到文件创建: {event.src_path}") # ... 后续代码
内容的提问来源于stack exchange,提问作者Baby Yoda
相关产品推荐
相关产品推荐

