使用openpyxl时为何Python代码仅能复制第二个工作簿,第一个无法复制?
问题:使用openpyxl仅能从第二个工作簿复制数据,第一个无法复制的原因?
我编写的Python代码逻辑看似正确,但使用openpyxl库时,仅能从第二个工作簿复制数据,无法从第一个工作簿复制,这是为什么?
核心问题分析
你的代码存在几个关键逻辑漏洞,导致第一个工作簿数据无法复制:
- 变量作用域错误:
get_data函数直接使用主循环中定义的ws21、ws22、wbn、file变量,但这些变量不在函数的作用域内。第一个文件处理时,函数无法找到这些变量,数据无法写入;第二个文件处理时,变量因循环泄漏意外可访问,才出现能复制的假象。 - 年份匹配规则不一致:2021的判断用了带前后空格的正则
r' 2021 ',但2022的判断是无空格的'2022',如果第一个文件名的2021没有前后空格,会直接跳过匹配,导致数据不复制。 - 未传递必要参数到函数:
get_data函数需要目标工作表、目标工作簿和保存路径等核心信息,但你没有将这些作为参数传入,完全依赖外部变量,属于严重的逻辑漏洞。 - 默认工作表未清理:创建新工作簿时,openpyxl会自动生成
Sheet工作表,未删除可能导致后续操作混乱,但不是数据不复制的直接原因。
修正后的代码
import openpyxl import os import re input_path = r'C:\Users\input' output_path = r'C:\Users\output' res = [] def subs(file_name): # 统一匹配带/不带空格的年份,替换为下划线 file_name = re.sub(r'\s?2021\s?', '_', file_name) file_name = re.sub(r'\s?2022\s?', '_', file_name) return file_name def get_data(file_path, target_ws, target_wb, save_path): # 加载源工作簿 wb = openpyxl.load_workbook(file_path, data_only=True) ws = wb['DRE'] # 复制数据到目标工作表 for row in ws: for cell in row: target_ws[cell.coordinate].value = cell.value # 保存目标工作簿 target_wb.save(save_path) return file_path # 遍历输入目录获取所有文件 for p in os.listdir(input_path): full_path = os.path.join(input_path, p) if os.path.isfile(full_path): res.append(p) for r in res: # 创建新工作簿并清理默认工作表 nw = openpyxl.Workbook() if 'Sheet' in nw.sheetnames: nw.remove(nw['Sheet']) # 处理文件名并创建对应工作表 file = subs(r) ws21 = nw.create_sheet('_2021') ws22 = nw.create_sheet('_2022') # 拼接保存路径并保存初始工作簿 save_full_path = os.path.join(output_path, file) nw.save(save_full_path) # 加载目标工作簿(也可直接使用nw对象简化逻辑) wbn = openpyxl.load_workbook(save_full_path, data_only=True) target_ws21 = wbn['_2021'] target_ws22 = wbn['_2022'] # 根据文件名判断年份,调用复制逻辑 source_full_path = os.path.join(input_path, r) if re.search(r'\s?2021\s?', source_full_path): get_data(source_full_path, target_ws21, wbn, save_full_path) elif re.search(r'\s?2022\s?', source_full_path): get_data(source_full_path, target_ws22, wbn, save_full_path)
修正说明
- 修复变量作用域:将
get_data函数需要的核心参数(目标工作表、工作簿、保存路径)传入,不再依赖外部变量。 - 统一年份匹配规则:使用
\s?匹配可选空格,确保带/不带空格的年份都能被正确识别。 - 清理默认工作表:删除openpyxl自动生成的
Sheet工作表,避免冗余。 - 用
os.path.join拼接路径:避免手动拼接路径的斜杠错误,提升代码兼容性。 - 优化逻辑:可直接使用创建的
nw对象操作,无需重新加载工作簿(代码中保留原有加载逻辑,也可按需简化)。
内容的提问来源于stack exchange,提问作者Pedro Vinícius Eloy
相关产品推荐
相关产品推荐

