不再手动复制和粘贴!Python整合海量Excel的最佳实践

198 阅读5分钟

假设你面对着一个庞大的文件军团(5000个excel),分散在各个文件夹里,而你的任务是将它们集结到一个统一的文件夹中。听起来像是一个费时费力的工作吗?不要担心,Python就是你的超能力!让我向你展示如何利用Python,在短短几分钟内完成这个看似不可能的任务。

先打个底:以理解为主,不够严谨,如果看完还是不会,那一定是我讲的不够好,千万别影响你们探索Python的兴趣。

思路解析

  • 首先,我们要使用一个循环来遍历这5000个文件所在的不同文件夹;
  • 然后,对于每个文件,我们用Python将它们轻松复制到一个统一的文件夹中,但是,注意了!如果目标文件夹中已经存在了同名文件,我们不能让它们相互踩脚。我们需要一点点创意,给每个重复的文件名后面加上一个独特的标记;
  • 最后,我们只需执行程序,就将以闪电般的速度完成这5000个文件的整理工作,同时,它会在日志中展示每个文件的复制过程;

开始之前,先讲下我们这次用到几个知识点

1.Python中文件复制的核心函数是shutil.copy2(),它可以复制文件的内容、权限和元数据。在Python中,同时也提供了shutil.copy()函数,但它只能复制文件的内容,无法保留文件的权限和元数据。
2.Python中遍历目录树的循环代码。
for root, dirs, files in os.walk(source_folder):

os.walk() 函数接受一个文件夹路径source_folder作为输入,并返回一个可迭代对象。在每次迭代中,它会返回一个三元组 (root, dirs, files),分别为当前文件夹、子文件夹、文件列表。其中root 是当前目录的路径,dirs 是当前目录中的子文件夹列表,files 是当前目录中的文件列表。 假设我们的根目录是/home/xusl/test_data,目录下有3个文件夹,如下图所示

  • root :/home/xusl/test_data
  • dirs:['新建文件夹3', '新建文件夹2', '新建文件夹1']
  • files:['新建文本文档.txt']

下次循环子目录内容,此时循环的是新建文件夹3,文件夹下有3个目录,分别是文件夹3目录1、 文件夹3目录、文件夹3目录3

  • root:/home/xusl/test_data/新建文件夹3
  • dirs:['文件夹3目录1', '文件夹3目录2', '文件夹3目录3']
  • files:[]

完整代码:

"""
Created on 2024/1/22
@title: ''
@author: Xusl
"""
import os
import shutil
import logging.config


_tb_nm = 'excel日志数据'
_tb_nm_cn = "excel日志数据"
_service_code = _tb_nm
# 日志目录
log_home = '/home/xusl/test_data'

# 日志level
log_level = logging.INFO

# 日志打印到控制台
log_to_console = True


log_config = {
    'version': 1,
    'formatters': {
        'generic': {
            'format': '%(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s',
        },
        'simple': {
            'format': '%(asctime)s %(levelname)-5.5s %(message)s',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'generic',
        },
        'file': {
            'class': 'logging.FileHandler',
            'filename': os.path.join(log_home, _tb_nm + '.log'),
            'encoding': 'utf-8',
            'formatter': 'generic',

        },
    },
    'root': {
        'level': log_level,
        'handlers': ['console', 'file', ] if log_to_console else ['file', ],
    }
}
logging.config.dictConfig(log_config)
logger = logging.getLogger(_tb_nm)


source_folder = '/home/xusl/test_data'                # 需要处理的文件夹路径
destination_folder = '/home/xusl/test_data/end'        # 保存路径

# 重名文件覆盖
# for root, dirs, files in os.walk(source_folder):
#     for file in files:
#         if file.endswith(".xlsx"):
#             source_path = os.path.join(root, file)
#             destination_path = os.path.join(destination_folder, file)
#             if not os.path.exists(destination_path):
#                 # 若目标文件不存在,直接复制
#                 print(f"Copying: {source_path} -> {destination_path}")
#                 shutil.copy(source_path, destination_folder)
#             else:
#                 # 若目标文件已存在,保留原有文件
#                 print(f"Duplicate found: {source_path}")


# 重名文件不覆盖
for root, dirs, files in os.walk(source_folder):
    #对于每个文件 file 在当前目录中的循环。
    for file in files:
        # if file.endswith(".xlsx"):  # 只处理excel文件,可放开注释
        # if file.endswith(".txt"):
        # 使用 os.path.join() 函数将目标文件夹路径 destination_folder 和文件名 file 连接起来,创建完整的目标文件路径 destination_path。
        source_path = os.path.join(root, file)
        destination_path = os.path.join(destination_folder, file)
        counter = 1
        # os.path.exists() 函数用于检查给定路径是否存在。
        while os.path.exists(destination_path):
            # 若目标文件已存在,添加后缀或编号
            file_name, file_ext = os.path.splitext(file)
            new_file_name = f"{file_name}_{counter}{file_ext}"
            destination_path = os.path.join(destination_folder, new_file_name)
            counter += 1
        logging.info(f"Copying: {source_path} -> {destination_path}")
        shutil.copy2(source_path, destination_path)

在循环中,我们使用os.path.splitext() 函数将文件名 file 拆分成文件名部分和扩展名部分。然后,我们创建一个新的文件名 new_file_name,在原始文件名后面添加一个下划线和计数器的值。最后,我们使用 os.path.join() 函数将目标文件夹路径 destination_folder 和新文件名 new_file_name 连接起来,更新目标文件路径 destination_path。计数器 counter 逐渐递增,直到找到一个不存在的目标文件路径。

如果看完以后还是不懂,没关系,只需要电脑配置Python环境,同时更改代码的三处目录即可执行,分别是

  • log_home:日志目录
  • source_folder:需要处理的文件夹路径
  • destination_folder:保存路径

写到最后,我真心希望大家都能学习Python,对于一些业务分析人员来说,掌握Python就可以轻松地提取、清洗和分析海量的数据,将繁琐的任务简化为几行代码。无论是数据分析、报告生成还是自动化处理,Python都能成为你最强大的助手。

同时不管你是从零开始还是已经有一定编程基础,Python都是一个友善且易于学习的语言。借助丰富的开源库和社区支持,你将能够快速提升自己的技能,为职场发展打下坚实的基础。

相信我,学习Python处理Excel文件不仅能够提高工作效率,还能为你带来更多的机会和可能性。所以一起努力,用Python的魔力开启新的职业篇章吧!