You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Python合并Excel中同文本颜色的单元格?

问题:合并Excel某列中相同文本颜色的单元格,且openpyxl无法检测黑色文本

我需要一个解决方案,用于合并Excel某一列中具有相同文本颜色的单元格。已有输入文件input_excel.xlsx,期望输出文件为output_excel.xlsx

我曾参考过基于单元格颜色和文本颜色筛选数据的相关内容,但无法合并黑色文本的单元格。我编写了如下代码用于检测Excel中的红色和黑色文本:

# importing openpyxl module
import openpyxl
# Give the location of the file
path = "E:\\input_excel.xlsx"
# workbook object is created
wb_obj = openpyxl.load_workbook(path)
sheet_obj = wb_obj.active
m_row = sheet_obj.max_row
for i in range(1, m_row + 1):
    cell_obj = sheet_obj.cell(row = i, column = 1).font.color
    if cell_obj is not None:
        # to catch cells that do have a color object
        if cell_obj.rgb == "FFFF0000":
            print(cell_obj.rgb)
        elif cell_obj.rgb == "00000000":
            print(cell_obj.rgb)

该代码仅能输出红色文本的十六进制值FFFF0000,无法检测到黑色文本。请问:

  1. 为何openpyxl无法检测黑色文本?
  2. 如何优化代码?
  3. 能否帮忙实现所需的合并功能?

解答

1. 为什么openpyxl检测不到黑色文本?

这是因为Excel中默认的黑色文本不会存储明确的颜色对象——只有当你手动修改过文本颜色(比如改成红色),Excel才会为该单元格的字体添加颜色属性。对于保持默认黑色的单元格,font.color会返回None,你的代码里if cell_obj is not None的判断直接跳过了这些单元格,自然检测不到黑色文本。另外你写的黑色RGB值00000000也不对,openpyxl中明确设置的黑色RGB是带透明度前缀的FF000000

2. 优化文本颜色检测的代码

我们需要调整逻辑:把font.colorNone的情况视为默认黑色,同时修正黑色的RGB值判断。优化后的检测代码如下:

import openpyxl

path = "E:\\input_excel.xlsx"
wb_obj = openpyxl.load_workbook(path)
sheet_obj = wb_obj.active
m_row = sheet_obj.max_row

for i in range(1, m_row + 1):
    cell = sheet_obj.cell(row=i, column=1)
    font_color = cell.font.color
    # 判断规则:None代表默认黑色,或者RGB为FF000000(手动设置的黑色)
    if font_color is None or font_color.rgb == "FF000000":
        print(f"行{i}:黑色文本")
    elif font_color.rgb == "FFFF0000":
        print(f"行{i}:红色文本")
    else:
        print(f"行{i}:其他颜色 {font_color.rgb}")

3. 实现相同文本颜色单元格的合并功能

要合并同颜色单元格,我们需要遍历目标列,记录连续同颜色的行范围,颜色变化时合并之前的连续行,最后处理最后一组连续行。完整实现代码如下:

import openpyxl
from openpyxl.styles import Alignment

def merge_cells_by_text_color(input_path, output_path, target_column=1):
    # 加载工作簿
    wb = openpyxl.load_workbook(input_path)
    ws = wb.active
    max_row = ws.max_row
    
    if max_row <= 1:
        wb.save(output_path)
        return
    
    # 初始化变量:记录当前颜色和连续行的起始位置
    current_cell = ws.cell(row=1, column=target_column)
    current_color = current_cell.font.color
    start_row = 1
    
    # 定义颜色匹配判断函数
    def colors_match(c1, c2):
        # 两种情况视为颜色相同:都是默认黑色(None),或者RGB值完全一致
        if c1 is None and c2 is None:
            return True
        elif c1 is not None and c2 is not None:
            return c1.rgb == c2.rgb
        return False
    
    # 遍历所有行
    for row in range(2, max_row + 1):
        cell = ws.cell(row=row, column=target_column)
        cell_color = cell.font.color
        
        if not colors_match(cell_color, current_color):
            # 合并上一段连续同颜色的单元格
            if start_row != row - 1:
                ws.merge_cells(start_row=start_row, start_column=target_column,
                              end_row=row-1, end_column=target_column)
                # 设置合并后单元格的居中对齐,提升美观度
                merged_cell = ws.cell(row=start_row, column=target_column)
                merged_cell.alignment = Alignment(vertical='center', horizontal='center')
            # 更新当前颜色和起始行
            current_color = cell_color
            start_row = row
    
    # 处理最后一组连续的同颜色单元格
    if start_row != max_row:
        ws.merge_cells(start_row=start_row, start_column=target_column,
                      end_row=max_row, end_column=target_column)
        merged_cell = ws.cell(row=start_row, column=target_column)
        merged_cell.alignment = Alignment(vertical='center', horizontal='center')
    
    # 保存结果文件
    wb.save(output_path)

# 调用函数完成合并
merge_cells_by_text_color("E:\\input_excel.xlsx", "E:\\output_excel.xlsx")

代码说明

  • colors_match函数专门处理颜色匹配逻辑,兼顾了默认黑色和手动设置颜色的情况
  • 合并单元格后自动设置居中对齐,避免合并后内容显示混乱
  • 支持指定目标列,默认处理第1列(A列),可根据需求修改参数

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

火山引擎 最新活动