当前位置:首页>python>第345讲:用Python和VBA两种方案批量文件重命名与归类整理

第345讲:用Python和VBA两种方案批量文件重命名与归类整理

  • 2026-10-11 06:57:10
第345讲:用Python和VBA两种方案批量文件重命名与归类整理

场景:将数百张产品图片按SKU编码重命名并归类到子文件夹

做电商运营、仓储管理或者产品摄影的朋友,大概率都遇到过这种“绝望”时刻:

相机导出的几百张产品图,文件名全是 IMG_001.jpg、DSC_002.png这种毫无意义的格式。而手头有一张Excel表,A列是旧文件名,B列是对应的SKU编码(比如 SKU-2024-001)。老板要求你:半小时内,把所有图片按SKU重命名,并且按品类(比如“男装”、“女装”、“配件”)放进不同的文件夹里。

手动改?点几百次鼠标,不仅慢,还容易漏。今天我们就用Python和VBA两种方案,彻底解决这个痛点。


一、需求拆解与准备工作

在开始写代码前,我们先把逻辑理清楚。这是避免写出“屎山代码”的关键一步。

1. 数据准备

假设你的文件夹结构是这样的:

D:\ProductPhotos\│  IMG_001.jpg│  IMG_002.jpg│  IMG_003.jpg│  mapping.xlsx

mapping.xlsx的内容如下:

旧文件名 (OldName)

SKU编码 (SKU)

品类 (Category)

IMG_001.jpg

SKU-2024-001

男装

IMG_002.jpg

SKU-2024-002

女装

IMG_003.jpg

SKU-2024-003

配件

2. 逻辑流程

无论是Python还是VBA,核心逻辑都是一致的:

  1. 读取映射表:从Excel中读取“旧文件名-SKU-品类”的对应关系。

  2. 遍历文件:扫描目标文件夹中的所有图片文件。

  3. 匹配与重命名:找到旧文件名对应的行,将其重命名为 SKU-2024-001.jpg。

  4. 创建目录:根据“品类”字段,创建对应的子文件夹(如“男装”)。

  5. 移动文件:将重命名后的文件移动到对应的子文件夹中。


二、Python方案:现代化与优雅的 pathlib

Python在处理文件批量操作时,有两个流派:一个是传统的 os+ shutil,另一个是更现代的 pathlib。强烈推荐使用 pathlib,因为它把路径当成对象来处理,代码可读性极高,且跨平台兼容性更好(不用操心Windows的反斜杠 \` 和Mac/Linux的正斜杠/` 问题)。

1. 核心库导入

import pandas as pdfrom pathlib import Pathimport shutil

2. 完整代码实现

下面的代码不仅实现了功能,还加入了异常处理和日志打印,这是专业脚本的标配。

def organize_product_photos(excel_path, photo_dir):    """    批量重命名并归类产品图片    :param excel_path: 映射表Excel路径    :param photo_dir: 图片文件夹路径    """    # 1. 读取Excel映射表    try:        df = pd.read_excel(excel_path)        # 清洗列名,去除可能存在的空格        df.columns = df.columns.str.strip()    except Exception as e:        print(f"读取Excel失败:{e}")        return    # 2. 定位图片文件夹    photo_path = Path(photo_dir)    # 3. 遍历DataFrame中的每一行映射关系    for index, row in df.iterrows():        old_name = row['旧文件名']        sku = row['SKU编码']        category = row['品类']        # 构建旧文件的完整路径        old_file = photo_path / old_name        # 检查旧文件是否存在        if not old_file.exists():            print(f"警告:文件 {old_name} 不存在,跳过。")            continue        # 4. 构建新文件名(保留原扩展名)        # 获取文件后缀,例如 .jpg        suffix = old_file.suffix        new_name = f"{sku}{suffix}"        # 5. 创建分类子文件夹        # mkdir(parents=True): 如果父目录不存在则创建        # exist_ok=True: 如果目录已存在则不报错        category_dir = photo_path / category        category_dir.mkdir(exist_ok=True)        # 6. 构建目标文件路径        target_file = category_dir / new_name        # 7. 移动并重命名        try:            # shutil.move 既可以移动也可以重命名            shutil.move(str(old_file), str(target_file))            print(f"成功:{old_name} -> {category}/{new_name}")        except Exception as e:            print(f"处理 {old_name} 失败:{e}")    print("所有文件处理完毕!")# 执行函数if __name__ == "__main__":    excel_file = r"D:\ProductPhotos\mapping.xlsx"    photos_folder = r"D:\ProductPhotos"    organize_product_photos(excel_file, photos_folder)

3. Python代码深度解析

  • pathlib的优势:photo_path / old_name这种写法非常直观,避免了 os.path.join()那种繁琐的字符串拼接。

  • shutil.move:这个函数很强大,如果源路径和目标路径在同一个磁盘,它相当于重命名;如果在不同磁盘,它会先复制再删除源文件。

  • 异常处理:try...except结构保证了即使某个文件处理失败,程序也不会崩溃,而是继续处理下一个文件。

  • __name__ == "__main__":这是Python的最佳实践,确保代码在被导入为模块时不会自动执行。

4. 进阶优化(干货)

如果你不想依赖 pandas(比如服务器环境没有安装),可以用 csv模块替代Excel读取:

import csvdef read_mapping_csv(csv_path):    mapping = []    with open(csv_path, 'r', encoding='utf-8-sig') as f: # utf-8-sig解决Windows下BOM问题        reader = csv.DictReader(f)        for row in reader:            mapping.append(row)    return mapping

三、VBA方案:Excel原生环境的利器

对于大多数办公室白领来说,VBA是离数据最近的开发工具。不需要安装Python环境,直接在Excel里就能跑。

1. 启用FileSystemObject (FSO)

VBA默认没有开启文件系统对象,需要手动引用:

  1. 打开VBA编辑器 (Alt + F11)。

  2. 点击菜单栏 工具-> 引用。

  3. 勾选 Microsoft Scripting Runtime。

2. 完整代码实现

这段代码可以直接放在Excel的VBA模块中运行。

Sub OrganizeProductPhotos()    Dim FSO As Scripting.FileSystemObject    Dim ws As Worksheet    Dim photoDir As String    Dim lastRow As Long    Dim i As Long    Dim oldName As String, sku As String, category As String    Dim oldFile As Object, categoryFolder As Object    Dim fileExt As String    ' 1. 设置工作表和路径    Set ws = ThisWorkbook.Sheets("Sheet1") ' 修改为你的Sheet名    photoDir = "D:\ProductPhotos\" ' 修改为你的图片路径    ' 2. 创建FileSystemObject    Set FSO = New Scripting.FileSystemObject    ' 3. 获取最后一行    lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row    ' 4. 循环处理每一行    For i = 2 To lastRow ' 假设第一行是表头        oldName = ws.Cells(i, 1).Value ' A列:旧文件名        sku = ws.Cells(i, 2).Value    ' B列:SKU编码        category = ws.Cells(i, 3).Value ' C列:品类        ' 检查旧文件是否存在        If FSO.FileExists(photoDir & oldName) Then            ' 5. 获取文件扩展名            fileExt = FSO.GetExtensionName(photoDir & oldName)            ' 6. 创建分类文件夹            If Not FSO.FolderExists(photoDir & category) Then                FSO.CreateFolder (photoDir & category)            End If            ' 7. 移动并重命名            ' Name 语句可以跨文件夹移动并重命名            On Error Resume Next ' 防止重名文件报错中断            Name photoDir & oldName As photoDir & category & "\" & sku & "." & fileExt            If Err.Number <> 0 Then                Debug.Print "重命名失败: " & oldName & " -> " & sku & "." & fileExt                Err.Clear            Else                Debug.Print "成功: " & oldName & " -> " & category & "\" & sku & "." & fileExt            End If            On Error GoTo 0        Else            Debug.Print "文件不存在: " & oldName        End If    Next i    MsgBox "处理完毕!"End Sub

3. VBA代码深度解析

  • FileSystemObject (FSO):这是VBA操作文件的瑞士军刀。FileExists检查文件,FolderExists检查文件夹,CreateFolder创建文件夹,GetExtensionName获取后缀。

  • Name语句:这是VBA特有的语法,用于重命名文件或移动文件。语法是 Name 原路径 As 新路径。它比FSO的 MoveFile方法更直接,但缺点是如果目标文件已存在,会报错,所以配合了 On Error Resume Next使用。

  • On Error Resume Next:VBA中的错误处理语句,遇到错误时跳过当前行继续执行,防止程序因单个文件错误而崩溃。


四、Python vs VBA:技术选型对照

这是本文的核心对照要点,帮助你在实际工作中做选择。

维度

Python (pathlib+ shutil)

VBA (FSO+ Name)

代码风格

面向对象,路径是对象,链式调用优雅 (path.parent.mkdir())

过程式,字符串拼接路径,代码相对冗长

可读性

极高,接近自然语言,维护成本低

中等,需要熟悉VBA语法和FSO对象模型

环境依赖

需要安装Python及 pandas库(或用 csv模块)

零依赖,Windows系统自带,Excel原生支持

错误处理

try...except结构清晰,捕获异常类型明确

On Error语句较为粗暴,调试相对困难

跨平台

完美支持 (Windows, macOS, Linux)

仅限Windows

性能

处理海量文件(上万级)时性能优势明显

处理几千个文件尚可,上万级可能卡顿

适用场景

复杂的数据清洗、自动化运维、跨平台脚本

快速处理Excel相关的小工具、办公自动化

总结建议:

  • 如果你是数据分析师或开发者,或者文件量巨大,请选 Python。

  • 如果你是行政、财务或运营,只想在现有Excel里快速解决问题,请选 VBA。


五、避坑指南(实战干货)

  1. 文件名编码问题:Windows系统经常遇到中文乱码。Python中读取文件时,如果遇到乱码,尝试指定编码 encoding='gbk'或 encoding='utf-8-sig'。

  2. 文件占用问题:如果图片正在被Windows照片查看器打开,代码执行时会报错(文件被占用)。确保处理前关闭所有相关文件。

  3. 重名覆盖风险:上述代码均未处理“目标文件已存在”的情况。在生产环境中,建议加入判断:如果目标文件存在,要么跳过,要么在文件名后加 _1、_2后缀。

  4. 路径末尾反斜杠:VBA中拼接路径时,很容易漏掉文件夹后的反斜杠 \`,导致路径变成D:\ProductPhotosIMG_001.jpg。使用FSO的BuildPath方法可以避免这个问题:FSO.BuildPath(photoDir, oldName)`。


六、课后练习

为了检验你对本文知识点的掌握程度,请完成以下选择题:

  1. 在Python的 pathlib模块中,用于连接路径和文件名的最佳方式是?

    A. os.path.join(path, name)

    B. path + "\\" + name

    C. path / name

    D. path.append(name)

  2. VBA中,FileSystemObject(FSO) 获取文件扩展名(如 "jpg")的方法是?

    A. FSO.GetFileName

    B. FSO.GetExtensionName

    C. FSO.GetFileType

    D. FSO.Extension

  3. 在Python中,使用 shutil.move(src, dst)时,如果 dst是一个已经存在的文件夹路径,会发生什么?

    A. 报错:文件已存在

    B. 将 src移动到 dst文件夹内

    C. 覆盖 dst文件夹

    D. 什么都不会发生

  4. VBA中的 Name语句主要功能是?

    A. 仅能重命名文件,不能移动文件

    B. 仅能移动文件,不能重命名

    C. 可以同时重命名和移动文件

    D. 用于定义变量名称

  5. 在处理批量文件重命名时,为了防止程序因单个文件处理失败而整体崩溃,Python和VBA分别通常采用什么机制?

    A. Python用 On Error Resume Next,VBA用 try...except

    B. Python用 try...except,VBA用 On Error Resume Next

    C. 两者都用 if...else判断

    D. 两者都没有内置的错误处理机制


答案

  1. C。pathlib重载了 /运算符,使得路径拼接更加直观和安全。

  2. B。GetExtensionName方法专门用于返回文件扩展名。

  3. B。如果目标是一个目录,shutil.move会将源文件移动到该目录下。

  4. C。VBA的 Name语句语法为 Name 原路径 As 新路径,新路径可以包含新的文件夹位置和新文件名。

  5. B。这是两者在错误处理语法上的核心区别。


如果这篇文章帮你解决了工作中的实际问题,欢迎点赞、在看、转发三连!有任何关于办公自动化的难题,也可以在评论区留言,我们下期再见。


最新文章

随机文章