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

Python实现Excel数据追加至CSV时列移位的代码问题求助

问题排查与修复方案

核心问题分析

你的代码出现数据偏移、原有列被覆盖的现象,根源是两个DataFrame的列名不匹配:

  • 从CSV加载的latest_df使用文件自带的表头作为列名
  • 从Excel提取的data_df使用默认的数字索引(0、1...87)作为列名

当执行pd.concat([latest_df, data_df], ignore_index=True)时,Pandas会按列名对齐,将两个DataFrame的所有列合并,导致原有CSV数据和新提取数据分别位于不同列组,看起来像是原有数据被右移,前88列被替换。

此外,代码还存在两个潜在问题:

  1. 重复打开/关闭Excel文件,可能引发文件锁定或缓存读取问题
  2. 提取Excel数据时未区分表头与数据行,可能导致结构混乱

修复后的代码

import os
import datetime
import win32com.client as win32
import pandas as pd

# 路径配置
network_path_endfile = r"K:\folder\name\endfile.xlsm"
network_folder_path_output = r"C:\folder2\name2\files"

# 初始化Excel应用
excel_app = win32.Dispatch('Excel.Application')
excel_app.Visible = False

# 优化宏执行:单次打开文件运行多个宏,减少文件操作
def run_macros(workbook_path, macro_names):
    workbook = excel_app.Workbooks.Open(workbook_path)
    for macro in macro_names:
        excel_app.Application.Run(f"'{workbook.Name}'!{macro}")
    workbook.Save()
    workbook.Close()

# 执行初始宏
run_macros(network_path_endfile, ['ProcessReports', 'DeleteRowsByCurrentMonthYear'])

# 获取上一工作日日期
today = datetime.datetime.today()
previous_business_day = today - datetime.timedelta(days=1)
# 处理周一的情况(回到上周五)
if today.weekday() == 0:
    previous_business_day -= datetime.timedelta(days=2)
previous_business_day_str = previous_business_day.strftime('%Y%m%d')

# 定位目标CSV文件
target_csv_name = f"concatenated_file_123_as_of_{previous_business_day_str}.csv"
target_csv_path = os.path.join(network_folder_path_output, target_csv_name)

# 加载CSV数据
latest_df = pd.read_csv(target_csv_path)

# 用Pandas读取Excel的1-88列(A到CH列),自动匹配列名
# 若Excel无表头,设置header=None后手动指定列名与CSV一致
data_df = pd.read_excel(network_path_endfile, usecols="A:CH", header=None)
data_df.columns = latest_df.columns  # 强制对齐列名

# 追加数据(此时列名完全匹配,会按行追加)
updated_df = pd.concat([latest_df, data_df], ignore_index=True)

# 保存更新后的CSV
updated_df.to_csv(target_csv_path, index=False)

# 执行最终宏并关闭Excel
run_macros(network_path_endfile, ['deleteall'])
excel_app.Quit()

关键修复点说明

  1. 统一列名对齐:通过data_df.columns = latest_df.columns强制让Excel提取的数据使用与CSV完全一致的列名,确保pd.concat按行追加而非合并列
  2. 优化宏执行逻辑:将多次打开/关闭Excel文件改为单次打开运行多个宏,避免文件访问冲突
  3. 简化Excel数据读取:用pd.read_excel替代openpyxl,更高效且便于列名控制
  4. 明确列范围:用usecols="A:CH"直接指定读取1-88列,避免索引错误

额外注意事项

  • 如果endfile.xlsm的第一行是表头,需将pd.read_excel的header参数改为0,并移除data_df.columns = latest_df.columns,避免重复设置表头
  • 若需要处理节假日的上一工作日,需引入第三方库(如holidays)来排除法定节假日
  • 运行代码前确保目标文件未被其他程序锁定

内容的提问来源于stack exchange,提问作者Sam Smith

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 20:54:51