You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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)

修正说明

  1. 修复变量作用域:将get_data函数需要的核心参数(目标工作表、工作簿、保存路径)传入,不再依赖外部变量。
  2. 统一年份匹配规则:使用\s?匹配可选空格,确保带/不带空格的年份都能被正确识别。
  3. 清理默认工作表:删除openpyxl自动生成的Sheet工作表,避免冗余。
  4. 用os.path.join拼接路径:避免手动拼接路径的斜杠错误,提升代码兼容性。
  5. 优化逻辑:可直接使用创建的nw对象操作,无需重新加载工作簿(代码中保留原有加载逻辑,也可按需简化)。

内容的提问来源于stack exchange,提问作者Pedro Vinícius Eloy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 15:47:02