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

Python使用pandas分类保存.xlsm宏Excel文件后文件损坏问题求助

问题原因
  • 你代码中保存的是预先定义的空DataFrame对象,没有写入原文件任何内容,生成的是空文件,所以打开时报错。
  • pandas的to_excel方法默认不支持保留xlsm文件的宏、控件、隐藏表等特殊内容,即使写入读取到的表格内容,也会丢失宏信息导致文件损坏。
  • 逻辑错误:你循环遍历每张工作表判断条件,每判断一张表就覆盖写入一次文件,同一个文件会被反复覆盖,逻辑混乱。
修复方案

你的需求是仅判断文件内容、原封不动分类保存原文件,完全不需要用pandas写入文件,只需要在判断完条件后,直接复制原文件到对应目录即可。
修复后的代码如下:

from pathlib import Path
import time
import argparse
import pandas as pd
import os
import shutil
import warnings

warnings.filterwarnings("ignore")

parser = argparse.ArgumentParser(description="Classify xlsm files by specified field.")
parser.add_argument("path", help="define the directory to folder/file")
parser.add_argument("--verbose", help="display processing information")

def main(path_xlsm, verbose):
    # 定义目标目录,不存在则创建
    peel_path = Path("C:\\Users\\ShantanuGupta\\Desktop\\Incoming\\Peel")
    resolution_path = Path("C:\\Users\\ShantanuGupta\\Desktop\\Incoming\\Resolution")
    peel_path.mkdir(parents=True, exist_ok=True)
    resolution_path.mkdir(parents=True, exist_ok=True)

    # 读取所有待处理xlsm文件
    if (".xlsm" in str(path_xlsm).lower()) and path_xlsm.is_file():
        xlsm_files = [Path(path_xlsm)]
    else:
        xlsm_files = list(Path(path_xlsm).glob("*.xlsm"))
    
    for fn in xlsm_files:
        match_flag = False
        # 读取文件所有工作表判断条件
        all_dfs = pd.read_excel(fn, sheet_name=None, header=None, engine="openpyxl")
        # 排除不需要判断的工作表
        for skip_sheet in ["Lookups", "Instructions For Use", "Drop Down Boxes", "ResolutionLookups"]:
            all_dfs.pop(skip_sheet, None)
        
        # 遍历剩余工作表判断是否符合条件
        for ws_name, df1 in all_dfs.items():
            try:
                if df1.iloc[3, 0] == "Client Representative" and df1.iloc[4, 1] == "DATE" and df1.iloc[4, 3] == "SHIFT":
                    match_flag = True
                    break # 找到符合条件的表就跳出循环
            except IndexError:
                # 部分工作表行数/列数不足,跳过判断
                continue
        
        # 按判断结果复制原文件到对应目录
        if match_flag:
            target_path = peel_path / fn.name
        else:
            target_path = resolution_path / fn.name
        shutil.copy2(fn, target_path) # copy2会保留文件原属性
        if verbose:
            print(f"文件{fn.name}已分类到{target_path.parent}")

if __name__ == "__main__":
    start = time.time()
    args = parser.parse_args()
    path = Path(args.path)
    verbose = args.verbose
    main(path, verbose)
    print("处理总耗时:", time.time() - start)
修复说明
  • 新增shutil.copy2直接复制原文件,100%保留原文件的所有内容、宏、属性信息,不会损坏文件
  • 优化了判断逻辑,同一个文件只需判断到符合条件的工作表就停止判断,避免重复操作
  • 新增目录自动创建逻辑,目标目录不存在时会自动生成,不会报路径不存在错误
  • 新增索引错误捕获,避免部分工作表行列数不足导致代码报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 17:09:05