Python 自动化 Excel 查找、替换内容


Python 自动化 Excel 查找、替换内容

Python 自动化 Excel 查找、替换内容详细教程

在处理Excel文件时,查找和替换是非常高频的操作。无论是批量修正错误内容、替换关键词、还是更新统一格式,Python都能高效完成。本文将详细介绍各种查找替换场景的实现方法,包含完整代码示例和最佳实践,批量处理效率远超手动操作。


一、环境准备

1.1 安装依赖库

bash
pip install openpyxl pandas

1.2 应用场景

查找替换功能非常实用,常见的使用场景包括:

  • 批量修正表格中的错别字、错误数据
  • 统一替换公司名称、部门名称、产品名称
  • 批量更新日期、版本号、联系方式等信息
  • 替换敏感词、屏蔽不合适内容
  • 统一数据格式,比如把”男”替换为”M”,”女”替换为”W”
  • 批量修改公式中的引用、参数等

  • 二、基础查找替换操作

    2.1 查找内容是否存在

    先检查Excel中是否包含特定内容:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("员工信息.xlsx")
    ws = wb["员工表"]
    
    search_text = "技术部"
    found = False
    found_cells = []
    
    # 遍历所有单元格
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell_value = ws.cell(row=row, column=col).value
            if cell_value and search_text in str(cell_value):
                found = True
                found_cells.append(f"{chr(64+col)}{row}")
    
    if found:
        print(f"✅ 找到内容'{search_text}',位置:{found_cells}")
    else:
        print(f"❌ 未找到内容'{search_text}'")
    

    2.2 简单替换内容

    把所有”技术部”替换为”研发中心”:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("员工信息.xlsx")
    ws = wb["员工表"]
    
    old_text = "技术部"
    new_text = "研发中心"
    replace_count = 0
    
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell_value = ws.cell(row=row, column=col).value
            if isinstance(cell_value, str) and old_text in cell_value:
                # 替换内容
                new_value = cell_value.replace(old_text, new_text)
                ws.cell(row=row, column=col, value=new_value)
                replace_count += 1
                print(f"✅ 替换单元格 {chr(64+col)}{row}:{cell_value} → {new_value}")
    
    wb.save("员工信息_替换后.xlsx")
    print(f"\n🎉 替换完成,共替换 {replace_count} 处")
    

    2.3 整列替换

    只在指定列中替换,效率更高:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("员工信息.xlsx")
    ws = wb["员工表"]
    
    # 只在部门列(B列)替换
    old_text = "技术部"
    new_text = "研发中心"
    replace_count = 0
    
    for row in range(2, ws.max_row + 1):  # 跳过表头
        cell_value = ws.cell(row=row, column=2).value  # column=2是B列
        if isinstance(cell_value, str) and old_text in cell_value:
            new_value = cell_value.replace(old_text, new_text)
            ws.cell(row=row, column=2, value=new_value)
            replace_count += 1
    
    wb.save("员工信息_列替换.xlsx")
    print(f"✅ 列替换完成,共替换 {replace_count} 处")
    

    2.4 使用pandas批量替换

    pandas替换更简单高效,适合大数据量:

    python
    import pandas as pd
    
    df = pd.read_excel("员工信息.xlsx")
    
    # 全局替换所有匹配的内容
    df = df.replace("技术部", "研发中心")
    print("✅ 全局替换完成")
    
    # 只在指定列替换
    df["部门"] = df["部门"].replace("技术部", "研发中心")
    print("✅ 指定列替换完成")
    
    # 批量替换多个内容
    replace_map = {
        "技术部": "研发中心",
        "产品部": "产品中心",
        "销售部": "营销中心",
        "人事部": "人力资源部"
    }
    df = df.replace(replace_map)
    print("✅ 批量多值替换完成")
    
    df.to_excel("员工信息_pandas替换.xlsx", index=False)
    

    三、高级查找替换技巧

    3.1 大小写不敏感替换

    替换时不区分大小写,比如”技术部”、”技术部”、”TECH”都能匹配:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("员工信息.xlsx")
    ws = wb["员工表"]
    
    old_text = "技术部".lower()
    new_text = "研发中心"
    replace_count = 0
    
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell_value = ws.cell(row=row, column=col).value
            if isinstance(cell_value, str) and old_text in cell_value.lower():
                # 保留原格式,只替换匹配部分
                import re
                # 不区分大小写替换
                new_value = re.sub(re.escape(old_text), new_text, cell_value, flags=re.IGNORECASE)
                ws.cell(row=row, column=col, value=new_value)
                replace_count += 1
    
    wb.save("员工信息_忽略大小写替换.xlsx")
    print(f"✅ 忽略大小写替换完成,共替换 {replace_count} 处")
    

    3.2 正则表达式替换

    支持复杂模式匹配,比如替换所有手机号、邮箱、日期等:

    python
    from openpyxl import load_workbook
    import re
    
    wb = load_workbook("联系信息.xlsx")
    ws = wb.active
    
    # 把所有手机号中间四位替换为****
    pattern = r"1(\d{2})\d{4}(\d{4})"
    replace_pattern = r"1\1****\2"
    replace_count = 0
    
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell_value = ws.cell(row=row, column=col).value
            if isinstance(cell_value, str):
                # 查找手机号并替换
                new_value, count = re.subn(pattern, replace_pattern, cell_value)
                if count > 0:
                    ws.cell(row=row, column=col, value=new_value)
                    replace_count += count
    
    wb.save("联系信息_手机号脱敏.xlsx")
    print(f"✅ 手机号脱敏完成,共处理 {replace_count} 个手机号")
    

    常用正则替换场景:

    python
    # 替换邮箱为***
    pattern = r"([a-zA-Z0-9._%+-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})"
    replace = r"***@\2"
    
    # 替换身份证号中间8位
    pattern = r"(\d{6})\d{8}(\d{4})"
    replace = r"\1********\2"
    
    # 统一日期格式,把2026/3/31替换为2026-03-31
    pattern = r"(\d{4})/(\d{1,2})/(\d{1,2})"
    replace = lambda m: f"{m.group(1)}-{int(m.group(2)):02d}-{int(m.group(3)):02d}"
    

    3.3 按条件替换

    满足特定条件才替换,比如给绩效为A的员工加薪:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("员工信息.xlsx")
    ws = wb["员工表"]
    
    replace_count = 0
    for row in range(2, ws.max_row + 1):
        performance = ws.cell(row=row, column=5).value  # E列绩效
        salary = ws.cell(row=row, column=4).value       # D列工资
        if performance == "A" and isinstance(salary, (int, float)):
            # 绩效为A的工资上涨10%
            new_salary = salary * 1.1
            ws.cell(row=row, column=4, value=new_salary)
            replace_count += 1
            print(f"✅ 更新员工{ws.cell(row=row, column=1).value}工资:{salary} → {new_salary}")
    
    wb.save("员工信息_条件替换.xlsx")
    print(f"\n✅ 条件替换完成,共更新 {replace_count} 人工资")
    

    3.4 多关键词批量替换

    同时替换多个关键词,适合敏感词过滤、统一术语等场景:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("文档.xlsx")
    ws = wb.active
    
    # 要替换的关键词映射
    keyword_map = {
        "旧公司名": "新公司名",
        "旧地址": "新地址",
        "旧电话": "新电话",
        "旧网址": "新网址",
        "敏感词1": "***",
        "敏感词2": "***"
    }
    
    replace_count = 0
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell_value = ws.cell(row=row, column=col).value
            if isinstance(cell_value, str):
                new_value = cell_value
                for old, new in keyword_map.items():
                    if old in new_value:
                        new_value = new_value.replace(old, new)
                        replace_count += 1
                if new_value != cell_value:
                    ws.cell(row=row, column=col, value=new_value)
    
    wb.save("文档_关键词替换.xlsx")
    print(f"✅ 多关键词替换完成,共替换 {replace_count} 处")
    

    四、工作表级/工作簿级替换

    4.1 替换指定工作表的内容

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("多工作表文件.xlsx")
    
    # 要处理的工作表列表
    sheets_to_process = ["1月销售", "2月销售", "3月销售"]
    old_text = "产品A"
    new_text = "旗舰产品A"
    total_replace = 0
    
    for sheet_name in sheets_to_process:
        if sheet_name in wb.sheetnames:
            ws = wb[sheet_name]
            replace_count = 0
            for row in range(1, ws.max_row + 1):
                for col in range(1, ws.max_column + 1):
                    cell_value = ws.cell(row=row, column=col).value
                    if isinstance(cell_value, str) and old_text in cell_value:
                        new_value = cell_value.replace(old_text, new_text)
                        ws.cell(row=row, column=col, value=new_value)
                        replace_count += 1
            total_replace += replace_count
            print(f"✅ 工作表{sheet_name}替换 {replace_count} 处")
    
    wb.save("多工作表文件_替换后.xlsx")
    print(f"\n✅ 所有工作表替换完成,共替换 {total_replace} 处")
    

    4.2 替换整个工作簿所有工作表的内容

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("整个工作簿替换.xlsx")
    
    old_text = "2025年"
    new_text = "2026年"
    total_replace = 0
    
    for ws in wb.worksheets:
        replace_count = 0
        for row in range(1, ws.max_row + 1):
            for col in range(1, ws.max_column + 1):
                cell_value = ws.cell(row=row, column=col).value
                if isinstance(cell_value, str) and old_text in cell_value:
                    new_value = cell_value.replace(old_text, new_text)
                    ws.cell(row=row, column=col, value=new_value)
                    replace_count += 1
        total_replace += replace_count
        print(f"✅ 工作表{ws.title}替换 {replace_count} 处")
    
    wb.save("整个工作簿替换_完成.xlsx")
    print(f"\n✅ 整个工作簿替换完成,共替换 {total_replace} 处")
    

    4.3 批量处理多个Excel文件

    替换某个文件夹下所有Excel文件中的内容:

    python
    import os
    from openpyxl import load_workbook
    
    folder_path = "需要替换的文件/"
    old_text = "旧公司名称"
    new_text = "新公司名称"
    total_files = 0
    total_replace = 0
    
    for filename in os.listdir(folder_path):
        if filename.endswith((".xlsx", ".xls")) and not filename.startswith("~$"):
            file_path = os.path.join(folder_path, filename)
            print(f"\n正在处理:{filename}")
            total_files += 1
            
            wb = load_workbook(file_path)
            file_replace = 0
            
            for ws in wb.worksheets:
                for row in range(1, ws.max_row + 1):
                    for col in range(1, ws.max_column + 1):
                        cell_value = ws.cell(row=row, column=col).value
                        if isinstance(cell_value, str) and old_text in cell_value:
                            new_value = cell_value.replace(old_text, new_text)
                            ws.cell(row=row, column=col, value=new_value)
                            file_replace += 1
            
            total_replace += file_replace
            # 保存文件,可以覆盖原文件或者另存为
            new_filename = f"替换后_{filename}"
            wb.save(os.path.join(folder_path, new_filename))
            print(f"✅ 完成,替换 {file_replace} 处,保存为{new_filename}")
    
    print(f"\n🎉 全部处理完成!共处理 {total_files} 个文件,替换 {total_replace} 处")
    

    五、查找替换的特殊场景

    5.1 查找替换公式

    不仅可以替换单元格内容,还可以替换公式:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("带公式的报表.xlsx")
    ws = wb.active
    
    # 把公式中的Sheet1替换为Data
    old_sheet = "Sheet1"
    new_sheet = "Data"
    replace_count = 0
    
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell = ws.cell(row=row, column=col)
            if cell.data_type == "f":  # 是公式
                formula = cell.value
                if old_sheet in formula:
                    new_formula = formula.replace(old_sheet, new_sheet)
                    cell.value = new_formula
                    replace_count += 1
    
    wb.save("带公式的报表_替换后.xlsx")
    print(f"✅ 公式替换完成,共替换 {replace_count} 个公式")
    

    5.2 替换超链接

    批量更新表格中的超链接:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("带超链接的文件.xlsx")
    ws = wb.active
    
    old_domain = "old-domain.com"
    new_domain = "new-domain.com"
    replace_count = 0
    
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell = ws.cell(row=row, column=col)
            if cell.hyperlink is not None:
                hyperlink = cell.hyperlink.target
                if old_domain in hyperlink:
                    new_hyperlink = hyperlink.replace(old_domain, new_domain)
                    cell.hyperlink.target = new_hyperlink
                    replace_count += 1
                    print(f"✅ 更新超链接:{hyperlink} → {new_hyperlink}")
    
    wb.save("带超链接的文件_更新后.xlsx")
    print(f"✅ 超链接替换完成,共更新 {replace_count} 个链接")
    

    5.3 仅替换整个单元格匹配的内容

    默认是包含匹配,只要单元格包含内容就替换,如果需要只有整个单元格完全匹配才替换:

    python
    from openpyxl import load_workbook
    
    wb = load_workbook("员工信息.xlsx")
    ws = wb["员工表"]
    
    old_text = "技术"
    new_text = "研发"
    replace_count = 0
    
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell_value = ws.cell(row=row, column=col).value
            # 只有完全相等才替换
            if cell_value == old_text:
                ws.cell(row=row, column=col, value=new_text)
                replace_count += 1
    
    wb.save("员工信息_完全匹配替换.xlsx")
    print(f"✅ 完全匹配替换完成,共替换 {replace_count} 处")
    

    5.4 替换后保留格式

    默认替换会保留原单元格格式,如果需要应用新格式:

    python
    from openpyxl import load_workbook
    from openpyxl.styles import Font, PatternFill
    
    wb = load_workbook("员工信息.xlsx")
    ws = wb["员工表"]
    
    old_text = "待转正"
    new_text = "已转正"
    replace_count = 0
    
    # 新格式:绿色加粗
    green_bold = Font(color="00B050", bold=True)
    green_fill = PatternFill(start_color="E6FFE6", end_color="E6FFE6", fill_type="solid")
    
    for row in range(1, ws.max_row + 1):
        for col in range(1, ws.max_column + 1):
            cell_value = ws.cell(row=row, column=col).value
            if isinstance(cell_value, str) and old_text in cell_value:
                new_value = cell_value.replace(old_text, new_text)
                cell = ws.cell(row=row, column=col, value=new_value)
                # 应用新格式
                cell.font = green_bold
                cell.fill = green_fill
                replace_count += 1
    
    wb.save("员工信息_替换带格式.xlsx")
    print(f"✅ 带格式替换完成,共替换 {replace_count} 处")
    

    六、常见问题与解决方案

    6.1 替换后数字变成字符串

    问题:替换后数字内容变成了字符串,无法计算

    解决方案

    替换后转换回正确的类型:
    python
    new_value = cell_value.replace(old_text, new_text)
    # 判断是否是数字
    if new_value.isdigit():
        new_value = int(new_value)
    elif new_value.replace('.', '', 1).isdigit():
        new_value = float(new_value)
    ws.cell(row=row, column=col, value=new_value)
    

    6.2 替换速度慢

    问题:大文件替换时速度很慢,几十MB的文件要处理很久

    解决方案

    用pandas处理,速度比openpyxl快10倍以上
    不需要修改格式的话,优先用pandas
    只处理需要的列,不要遍历所有单元格
    用正则表达式批量匹配,减少循环次数

    6.3 替换不生效

    问题:明明内容存在,但替换不成功

    原因排查

    1. 检查是否有空格、特殊字符、大小写不一致

    2. 检查单元格类型是不是字符串,数字、日期等类型需要先转字符串

    3. 可能是单元格有隐藏的格式或者空格,用strip()去除空白字符:

    python
    if isinstance(cell_value, str):
        cell_value = cell_value.strip()
        if old_text in cell_value:
            # 替换逻辑
    

    6.4 替换后公式错误

    问题:替换单元格内容后,相关公式出现#REF!错误

    解决方案

    替换公式时要确保引用的工作表、单元格存在
    替换前先备份原文件
    替换后打开文件检查公式是否正常
    重要公式建议先转换成数值再替换

    6.5 中文乱码问题

    问题:替换后中文显示乱码

    解决方案

    确保Python文件编码是UTF-8
    读取和保存时指定编码:`load_workbook(filename, encoding=’utf-8′)`
    避免用特殊字符作为替换内容

    七、最佳实践

    1. 替换前备份:任何修改前都先备份原文件,避免替换错误无法恢复

    2. 先查找再替换:正式替换前先运行一次查找,确认要替换的内容和位置正确,避免误替换

    3. 小范围测试:批量替换前先测试1-2个文件,确认替换逻辑正确

    4. 记录替换日志:批量替换时记录替换的文件、位置、替换前后内容,方便后续核查

    5. 优先指定范围:能指定列、指定工作表的就不要全局替换,提升速度和准确性

    6. 复杂场景用正则:模糊匹配、格式统一、数据脱敏等场景优先用正则表达式

    7. 验证结果:替换完成后一定要打开文件检查,尤其是包含公式、格式的文件

    查找替换是Excel自动化中非常实用的功能,掌握这些方法可以大幅提升办公效率,尤其是批量处理大量文件时,效率是手动操作的几十上百倍。记住替换前一定要备份,避免误操作导致数据丢失!

    © 版权声明

    相关文章

    暂无评论

    none
    暂无评论...