灌水唠嗑区
技术分享
文章

Python 自动化办公系列(02)文件批量更名

发表于2025-09-29 10:57:1559次浏览6个评论

# -*- coding: utf-8 -*-
__author__  = 'Hao Jun'
__doc__ = '扫描图档文件批量更名为 "证书编号_姓名" 格式'
'''
2023年以前,盖章后的纸质证书需要通过扫描仪生成电子图档归档。
批量扫描,图档文件名一般为 "{随机字母}日期前缀_{三、四位数字}.jpg/pdf",
需要统一更名为"证书编号_姓名" 格式,方便搜索
'''
import pandas as pd
from enum import Enum
import os
import re

SN_LEGNTH = 4 # 扫描仪自动序号长度

sourceDir = r"H:\TempFiles" # 存放扫描图档文件的目录
lstSourceFileName = None
dicTargetFileName = {} # 新文件名称字典

# 证书信息文档
excelFile = r"工作模板.xlsx"
# 一下是工作模板示例数据。ID表达的是扫描图档的序号,所以纸质证书扫面的顺序必须按照工作模板中的ID顺序。纸质证书按照证书编号排序也是很容易的。

ID人员姓名证书编号电子文档名
1X里GDCA8a202212A001GDCA8a202212A001_X里.png
2XX光GDCA8a202212A002GDCA8a202212A002_XX光.png
3X朋GDCA8a202212A003GDCA8a202212A003_X朋.png
4XX林GDCA8a202212A004GDCA8a202212A004_XX林.png
5X禹GDCA8a202212A005GDCA8a202212A005_X禹.png
6XX赐GDCA8a202212A006GDCA8a202212A006_XX赐.png
7XX军GDCA8a202212A007GDCA8a202212A007_XX军.png
8XX风GDCA8a202212A008GDCA8a202212A008_XX风.png
9XX伟GDCA8a202212A009GDCA8a202212A009_XX伟.png
10XX琴GDCA8a202212A010GDCA8a202212A010_XX琴.png
11X楠GDCA8a202212A011GDCA8a202212A011_X楠.png
12XX峰GDCA8a202212A012GDCA8a202212A012_XX峰.png

data = pd.DataFrame(pd.read_excel(excelFile,keep_default_na=False)) # Need install module named 'xlrd'

class KEYS(Enum):
    COLUMN_ID = "ID"
    COLUMN_NAME = "人员姓名"
    COLUMN_CERTCODE = "证书编号"
    #COLUMN_CERTTYPE = "证书类型"

# 检查工作模板必要的表头
def chkExcelHead():
    excelColumns = data.columns.to_list() # 从 Excel 文件读出来的表头,转换成列表
    bExit = True
    for oKey in KEYS:
        if oKey.value not in excelColumns:
            print('在"{0}"中找不到表头"{1}"!'.format(excelFile,oKey.value))
            bExit = False
            break
    return bExit

def file_filter(f):
    # 正则表达式:字符开头、后面可能跟一个下划线,序号是两个以上的数字,后缀名是jpg或者pdf
    if re.match("^[\w-]+[_]?[\d]{2,}.(jpg|pdf)$",f):
        return True
    else:
        return False

if __name__=='__main__':
    if not chkExcelHead():
        exit(1) # 第一次发现不存在表头即退出程序

    # 这里的file_filter是过滤器函数。在sourceDir中搜索出符合file_filter函数内正则匹配规则的文件名
    lstSourceFileName = list(filter(file_filter,os.listdir(sourceDir)))

    for i in range(len(data)):
        #certType = data.loc[i, KEYS.COLUMN_CERTTYPE.value]
        #if certType != "纸质证书": continue  # 非纸质证书忽略
        id = data.loc[i, KEYS.COLUMN_ID.value]
        if id == '': continue  # ID 栏位为空的数据忽略
        name = data.loc[i, KEYS.COLUMN_NAME.value]
        certCode = data.loc[i, KEYS.COLUMN_CERTCODE.value]
        # 从 excel 文件中读取序号对应的图档名称(证书编号_姓名)
        #dicTargetFileName.update(dict([("{0:03d}".format(int(id)), "{0}_{1}".format(certCode,name))]))
        dicTargetFileName.update(dict([(int(id), "{0}_{1}".format(certCode, name))])) # [2023.10.10] 由于新扫描仪缺省四位序号

    for sourceFile in lstSourceFileName:
        dotIndex = sourceFile.rindex('.')
        if '_' in sourceFile:
            sn = int(sourceFile[sourceFile.rindex('_')+1:dotIndex]) # 从源文件右边开始搜索下划线
        else:
            sn = sourceFile[dotIndex-SN_LEGNTH:dotIndex] # 针对定长序号前没有下划线
        ext = sourceFile.split('.')[1]
        if dicTargetFileName.get(sn) is None:continue
        targetFile = dicTargetFileName.get(sn) + '.' + ext
        try:
            os.rename(sourceDir+"\\"+sourceFile, sourceDir+"\\"+targetFile)
            print("rename {0} to {1}".format(sourceFile,targetFile))
        except BaseException as e:
            print("Error occurred when rename {0} : {1}".format(sourceFile,e))
    pass
 

评论

登录后才可以发表评论
星雨楼发表于 10个月前
顶一下
shenggong发表于 10个月前
收藏了
用户头像
levvel发表于 9个月前
给你点个赞
用户头像
levvel发表于 8个月前
评论是对发帖人的一种尊重
崔哥发表于 4个月前
浅浅余寒春半,雪消蕙草初长。烟迷柳岸旧池塘。风吹梅蕊闹,雨细杏花香。月堕枝头欢意,从前虚梦高唐,觉来何处放思量。如今不是梦,真个到伊行。
gbase0001发表于 1个月前
谢谢分享,学到了。