一键净化Excel数据:高性能Python脚本实现多核并行清理

摘要

本文分享两个基于Python的Excel数据净化脚本,通过多进程并行技术清除工作表内不可见字符、批注、单元格样式等冗余内容,利用OpenPyXL实现底层操作,结合tqdm进度条和进程级任务分配,可快速处理百万级单元格数据。适用于数据分析预处理、跨系统数据迁移等场景。

脚本一:并行处理统一(单)进度条版本

架构设计:

主进程 初始化进程池 分配工作表任务 进程1处理整表 进程2处理整表 单元格清洗流水线 清除不可见字符 移除批注 重置样式 保存临时文件 合并处理结果

源码:

python 复制代码
import openpyxl
from openpyxl.styles import NamedStyle, Font, Border, PatternFill
from openpyxl.formatting import Rule
import re
from tqdm import tqdm
import multiprocessing
from functools import partial

def clean_invisible_chars(text):
    """清除字符串中的不可见字符"""
    if not isinstance(text, str):
        return text
    return re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', '', text)

def process_cell(cell, no_style, no_fill, cleared_list):
    """处理单个单元格的并行化函数"""
    # 清除单元格所有样式
    cell.fill = no_fill
    cell.font = Font(name='Calibri', size=11, bold=False, italic=False)
    cell.border = Border()
    cell.number_format = 'General'
    
    # 清除不可见字符
    if cell.value and isinstance(cell.value, str):
        cell.value = clean_invisible_chars(cell.value)
        cleared_list.append('不可见字符')
        
    # 清除批注
    if cell.comment:
        cell.comment = None
        cleared_list.append('批注')
        
    # 清除样式
    cell.style = no_style
    cleared_list.append('单元格样式')

def process_sheet(args):
    """处理整个工作表的并行化函数"""
    input_file, output_file, sheet_name = args
    cleared_items = set()
    
    # 每个进程独立处理一个完整的工作表
    wb = openpyxl.load_workbook(input_file)
    ws = wb[sheet_name]
    no_style = NamedStyle(name="Normal")
    no_fill = PatternFill(fill_type=None)
    
    # 清除所有条件格式
    ws.conditional_formatting = []
    cleared_items.add('条件格式填充色')
    
    total_rows = ws.max_row
    total_cols = ws.max_column
    
    # 使用tqdm显示进度
    for row in tqdm(ws.iter_rows(), total=total_rows, desc=f"处理 {sheet_name}"):
        for cell in row:
            # 清除单元格所有样式
            cell.fill = no_fill
            cleared_items.add('背景填充色')
            cell.font = Font(name='Calibri', size=11, bold=False, italic=False)
            cell.border = Border()
            cell.number_format = 'General'
            cell.style = no_style
            cleared_items.add('单元格样式')
            
            # 清除不可见字符
            if cell.value and isinstance(cell.value, str):
                cell.value = clean_invisible_chars(cell.value)
                cleared_items.add('不可见字符')
                
            # 清除批注
            if cell.comment:
                cell.comment = None
                cleared_items.add('批注')
    
    # 保存临时文件
    temp_file = f"temp_{sheet_name}.xlsx"
    wb.save(temp_file)
    
    return (temp_file, sheet_name, list(cleared_items))

def clear_all_and_save(input_file, output_file, sheet_name, num_processes=None):
    """
    多进程并行清除工作表中的:
    1. 不可见字符
    2. 批注
    3. 单元格样式
    """
    if num_processes is None:
        num_processes = multiprocessing.cpu_count()
    
    print(f"使用 {num_processes} 个进程并行处理...")
    
    # 准备参数 (这里可以扩展为处理多个sheet)
    args = [(input_file, output_file, sheet_name)]
    
    # 创建进程池
    with multiprocessing.Pool(processes=num_processes) as pool:
        results = list(tqdm(pool.imap(process_sheet, args), total=len(args), desc="总进度"))
    
    # 合并处理结果
    cleared_items = set()
    for temp_file, sheet_name, items in results:
        cleared_items.update(items)
        # 这里可以添加合并多个临时文件的逻辑
    
    # 保存最终工作簿 (简化处理,直接使用第一个结果)
    import shutil
    shutil.move(results[0][0], output_file)
    
    cleared_text = "\n".join(f"  ✔ 清除-{item}" for item in cleared_items)
    print("已完成:\n"+cleared_text+f"\n并保存到 {output_file}")

if __name__ == '__main__':
    input_excel_file = '测试文件.xlsx' # 原始文件
    output_excel_file = '清除样式_测试文件_并行版.xlsx' # 生成文件
    sheet_to_clean = 'sheet1' # sheet name
    
    print(f"输入文件: {input_excel_file}")
    print(f"输出文件: {output_excel_file}")
    print(f"目标工作表: {sheet_to_clean}")
    
    try:
        clear_all_and_save(input_excel_file, output_excel_file, sheet_to_clean)
    except Exception as e:
        print(f"处理过程中发生错误: {str(e)}")

脚本二:多核独立进度条版本

架构设计:

主进度条 启动N个Worker进程 进程0进度条 进程1进度条 单元格样式处理器 字符过滤器 批注清除器 生成校验日志 多文件聚合器 最终输出文件

源码:

python 复制代码
import openpyxl
from openpyxl.styles import NamedStyle, Font, Border, PatternFill
from openpyxl.formatting import Rule
import re
from tqdm import tqdm
import multiprocessing
from functools import partial

def clean_invisible_chars(text):
    """清除字符串中的不可见字符"""
    if not isinstance(text, str):
        return text
    return re.sub(r'[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]', '', text)

def process_sheet(args):
    """处理整个工作表的并行化函数"""
    input_file, output_file, sheet_name, process_idx = args
    cleared_items = set()
    
    # 每个进程独立处理一个完整的工作表
    wb = openpyxl.load_workbook(input_file)
    ws = wb[sheet_name]
    no_style = NamedStyle(name="Normal")
    no_fill = PatternFill(fill_type=None)
    
    # 清除所有条件格式
    ws.conditional_formatting = []
    cleared_items.add('条件格式填充色')
    
    total_rows = ws.max_row
    total_cols = ws.max_column
    
    # 使用多行进度条(position参数控制行位置)
    process_idx = args[3]  # 获取进程索引
    for row in tqdm(ws.iter_rows(), total=total_rows, 
                   desc=f"进程{process_idx}", position=process_idx+1):
        for cell in row:
            # 清除单元格所有样式
            cell.fill = no_fill
            cell.font = Font(name='Calibri', size=11, bold=False, italic=False)
            cell.border = Border()
            cell.number_format = 'General'
            cell.style = no_style
            cleared_items.update(['背景填充色', '单元格样式'])
            
            # 清除不可见字符
            if cell.value and isinstance(cell.value, str):
                cell.value = clean_invisible_chars(cell.value)
                cleared_items.add('不可见字符')
                
            # 清除批注
            if cell.comment:
                cell.comment = None
                cleared_items.add('批注')
    
    # 保存临时文件
    temp_file = f"temp_{sheet_name}.xlsx"
    wb.save(temp_file)
    
    return (temp_file, sheet_name, list(cleared_items))

def clear_all_and_save(input_file, output_file, sheet_name, num_processes=None):
    """
    多进程并行清除工作表中的:
    1. 不可见字符
    2. 批注
    3. 单元格样式
    """
    if num_processes is None:
        num_processes = multiprocessing.cpu_count()
    
    print(f"使用 {num_processes} 个进程并行处理...")
    
    # 准备参数并添加进程索引
    args = [(input_file, output_file, sheet_name, i) for i in range(num_processes)]
    # 确保至少有一个参数组
    if not args:
        args = [(input_file, output_file, sheet_name, 0)]
    
    # 创建进程池并显示总进度
    with multiprocessing.Pool(processes=num_processes) as pool:
        # 在主进度条下方显示各进程进度
        with tqdm(total=len(args), desc="总进度", position=0) as pbar:
            results = []
            for result in pool.imap(process_sheet, args):
                results.append(result)
                pbar.update()
    
    # 合并处理结果
    cleared_items = set()
    for temp_file, sheet_name, items in results:
        cleared_items.update(items)
        # 这里可以添加合并多个临时文件的逻辑
    
    # 保存最终工作簿 (简化处理,直接使用第一个结果)
    import shutil
    shutil.move(results[0][0], output_file)
    
    cleared_text = "\n".join(f"  ✔ 清除-{item}" for item in cleared_items)
    print("已完成:\n"+cleared_text+f"\n并保存到 {output_file}")

if __name__ == '__main__':
    input_excel_file = '测试文件.xlsx' # 原始文件
    output_excel_file = '清除样式_测试文件_并行版.xlsx' # 生成文件
    sheet_to_clean = 'sheet1' # sheet name
    
    print(f"输入文件: {input_excel_file}")
    print(f"输出文件: {output_excel_file}")
    print(f"目标工作表: {sheet_to_clean}")
    
    try:
        clear_all_and_save(input_excel_file, output_excel_file, sheet_to_clean)
    except Exception as e:
        print(f"处理过程中发生错误: {str(e)}")

核心清除能力

  • 数据净化:过滤ASCII 0-31不可见控制字符
  • 元数据清理:彻底清除单元格批注内容
  • 样式重置
    • 移除条件格式规则
    • 重置字体为Calibri 11pt
    • 清除所有填充颜色
    • 移除单元格边框样式
  • 性能优化
    • 多进程负载均衡
    • 基于CPU核心数自动扩展
    • 无锁内存独立操作

适用场景

  1. 第三方系统导出的脏数据清洗
  2. 金融数据脱敏后标准化处理
  3. 跨平台迁移Excel文件前的格式转换
  4. 机器学习数据预处理阶段
  5. 定期自动化报表生成前的重置
相关推荐
小九九的爸爸2 小时前
前端想要入门Agent开发,要具备哪些Python基础?
python·agent·ai编程
阿耶同学3 小时前
手把手教你用 LangGraph 搭建三层嵌套 Agent 架构
python·程序员
花酒锄作田20 小时前
Pydantic校验配置文件
python
hboot20 小时前
AI工程师第四课 - 深度学习入门
pytorch·python·神经网络
ZhengEnCi1 天前
P2M-Matplotlib折线图完全指南-从数据可视化到趋势分析的Python绘图利器
python·matlab·数据可视化
ZhengEnCi1 天前
P2L-Matplotlib饼图完全指南-从数据可视化到图表定制的Python绘图利器
python·matlab
曲幽1 天前
你的REST接口还在“过度投喂”数据吗?——FastAPI + GraphQL实战避坑指南
python·fastapi·web·graphql·route·cors·rest·strawberry
用户8358086187911 天前
基于 Self-RAG 与列表级重排序的进阶 RAG 系统设计与实现
python
Warson_L2 天前
Python `Annotated` 与 LangGraph Reducer 学习笔记
python
韩师傅2 天前
海天线算法的前世今生
python·计算机视觉