You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速Python实现Excel表格的条件单元格高亮?

提升Excel条件着色Python代码运行速度的实用方案

你的代码慢的核心原因是openpyxl逐单元格设置样式的开销极大——10万行×3列就是30万次单元格操作,每个操作都会触发内部对象更新,自然耗时惊人。下面是几个能大幅提速的方法:

方法1:用openpyxl内部样式数组批量修改(无需换库)

openpyxl有隐藏的_style_array接口,可以直接操作样式数组,避免逐单元格修改,能把速度提升几十倍。

修改后的代码:

import openpyxl
from openpyxl.styles import PatternFill, Font
import time

# 创建示例数据(和原代码一致)
wb = openpyxl.Workbook()
ws = wb.active
headers = ["ID", "Type", "Value"]
for col, header in enumerate(headers, 1):
    ws.cell(row=1, column=col, value=header)
for row in range(2, 100002):
    ws.cell(row=row, column=1, value=row-1)
    ws.cell(row=row, column=2, value="Type 1" if row % 3 == 0 else 
            "Type 2" if row % 3 == 1 else "Type 3")
    ws.cell(row=row, column=3, value=f"Value {row-1}")

# 预定义样式,字体只创建一次
bold_font = Font(bold=True)
fills = {
    "Type 1": PatternFill(start_color="FFF2CC", end_color="FFF2CC", fill_type="solid"),
    "Type 2": PatternFill(start_color="DBEEF4", end_color="DBEEF4", fill_type="solid"),
    "Type 3": PatternFill(start_color="FFC0CB", end_color="FFC0CB", fill_type="solid")
}

start = time.perf_counter()

# 获取工作表的样式数组
ws_style = ws._style_array
col_count = len(headers)

for row_idx in range(2, ws.max_row + 1):
    category = ws.cell(row=row_idx, column=2).value
    fill = fills.get(category)
    if fill:
        # 计算当前行在样式数组中的起始索引
        row_start = (row_idx - 1) * col_count
        # 批量修改当前行所有单元格的样式
        for col in range(col_count):
            style_idx = row_start + col
            new_style = ws_style[style_idx].copy(fill=fill, font=bold_font)
            ws_style[style_idx] = new_style

# 更新工作表样式
ws._style_array = ws_style

print(f"运行耗时: {time.perf_counter() - start:.2f} 秒")
wb.save("output.xlsx")

方法2:换用Pandas+XlsxWriter(速度最快)

如果可以切换库,Pandas配合XlsxWriter是处理大表格样式的最优解——它支持直接通过条件格式整行着色,不需要遍历任何单元格,速度能提升上百倍。

示例代码:

import pandas as pd
import time

start = time.perf_counter()

# 生成示例数据
data = []
for row in range(1, 100001):
    type_val = "Type 1" if row % 3 == 0 else "Type 2" if row % 3 == 1 else "Type 3"
    data.append({"ID": row, "Type": type_val, "Value": f"Value {row}"})

df = pd.DataFrame(data)

# 用XlsxWriter写入Excel
writer = pd.ExcelWriter("output_pandas.xlsx", engine="xlsxwriter")
df.to_excel(writer, sheet_name="Sheet1", index=False)
workbook = writer.book
worksheet = writer.sheets["Sheet1"]

# 定义三种格式
format_type1 = workbook.add_format({"bg_color": "#FFF2CC", "bold": True})
format_type2 = workbook.add_format({"bg_color": "#DBEEF4", "bold": True})
format_type3 = workbook.add_format({"bg_color": "#FFC0CB", "bold": True})

# 应用整行条件格式:根据B列的值匹配样式
worksheet.conditional_format(1, 0, df.shape[0], df.shape[1]-1, {
    "type": "formula",
    "criteria": '=$B2="Type 1"',
    "format": format_type1
})
worksheet.conditional_format(1, 0, df.shape[0], df.shape[1]-1, {
    "type": "formula",
    "criteria": '=$B2="Type 2"',
    "format": format_type2
})
worksheet.conditional_format(1, 0, df.shape[0], df.shape[1]-1, {
    "type": "formula",
    "criteria": '=$B2="Type 3"',
    "format": format_type3
})

writer.close()

print(f"运行耗时: {time.perf_counter() - start:.2f} 秒")

方法3:小优化(不换库不改逻辑)

如果暂时不想改大结构,至少把重复创建的Font对象抽出来复用——原代码每次循环都创建Font(bold=True),会产生大量冗余对象,拖慢速度:

修改原代码的循环部分:

# 提前创建字体对象,只创建一次
bold_font = Font(bold=True)

for row_idx in range(2, ws.max_row + 1):
    category = ws.cell(row=row_idx, column=2).value
    fill = fills.get(category)
    
    if fill:
        for cell in ws[row_idx]:
            cell.fill = fill
            cell.font = bold_font  # 复用预创建的对象

内容的提问来源于stack exchange,提问作者user321627

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 09:12:02