繁体   English   中英

如何使用openpyxl根据python中的特定条件格式化excel文件的行?

[英]How to format row of excel file based on specific condition in python using openpyxl?

我想突出显示 excel 文件中的特定行,就像在任何行中出现特定关键字时,它应该突出显示该行。 例如:打开下图,看看“每周平均”一词何时出现在任何行中,它应该突出显示该特定行。

图片:

单击此链接查看图像

当前编码:

wb = openpyxl.load_workbook(filename = excel_filename)
sheet_obj = wb.active
sheet_obj.delete_cols(1)

sheet = wb.get_sheet_by_name('Sheet1')
red_font = openpyxl.styles.Font(bold=True)

for row in sheet.iter_rows(values_only=True):
    if 'Weekly Avg' in row:
        for cell in row:
             sheet[str(cell.coordinate)].font = red_font

wb.save(excel_filename)

我尝试了以下方式并成功运行,但我无法突出显示整行在这里看图片 .

col = "ABCDEFG"              # to get column
wb = openpyxl.load_workbook(filename = excel_filename)
sheet_obj = wb.active
sheet_obj.delete_cols(1)

sheet = wb.get_sheet_by_name('Sheet1')
for cell in sheet["A"]:
    if "Weekly Avg" in cell.value:
        for i in range(0, len(col)):
            cell_coordinate = col[i]+str(cell.row)            # create cell ID
            sheet[cell_coordinate].font = openpyxl.styles.Font(color='000000FF', bold=True)
wb.save(excel_filename)

你快到了!

在处理openpyxl时,我倾向于不必依赖rowscolumns的硬编码值,因为数据是动态的并且可以轻松更改以抵消您的硬编码值。 虽然我的解决方案并不完美,但我已经在Python 3.6openpyxl 3.0.6上对其进行了测试,它生成了所需的 output。我相信可以改进逻辑以避免资源密集型for循环。

我选择使用Named Styles因为我们将格式应用于许多cells并且根据openpyxl styles文档,

与 Cell Styles 不同,Named Styles 是可变的。 当您想一次将格式应用于许多不同的单元格时,它们很有意义。

逻辑的 rest 应该从注释中不言自明。

import os
from pathlib import Path
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter
from openpyxl.styles import Font, PatternFill, Border, Side, Alignment, NamedStyle


# Define the colors to style the cells
BLACK = "000000"
YELLOW = "FFFF00"

# Define the cell fonts and fills
avg_cell_font = Font(name="Calibri", size=10, color=BLACK, bold=True)
avg_rows_fill = PatternFill(fill_type="solid", fgColor=YELLOW)

# Named style for the average totals rows
avg_totals_style = NamedStyle(
    name="avgTotals",
    font=avg_cell_font,
    fill=avg_rows_fill,
)

# load the workbook
excel_filename = Path(os.path.dirname(os.path.realpath(__file__))).joinpath(
    "averages_test_data.xlsx"
)
wb = load_workbook(filename=excel_filename)

# Register the named style cell formats to the workbook
if avg_totals_style.name not in wb.style_names:
    wb.add_named_style(avg_totals_style)

# get worksheet to apply formats to
ws = wb.active

# get minimum and maximum row numbers with data as strings
first_row_str = str(ws.min_row)
last_row_str = str(ws.max_row)

# get column letters of first and last columns with data
first_col_str = get_column_letter(ws.min_column)
last_col_str = get_column_letter(ws.max_column)

for row_index, row_data in enumerate(
    ws[f"{first_col_str}{first_row_str}:{last_col_str}{last_row_str}"]
):
    avg_total_str = "Weekly Avg"
    avg_totals_check = False
    avg_total_rows = []

    for cell in row_data:
        # check if the cell contains a value
        if cell.value:
            # if any cell contains the "Weekly Avg" string value
            # update the avg_totals_check flag and append that
            # row number to the avg_total_rows list
            if avg_total_str in str(cell.value):
                avg_totals_check = True
                avg_total_rows.append(str(cell.row))

    # if the avg_totals_check flag is True, then
    # iterate each cell in the row number strings in the
    # avg_total_rows list and apply a style to the cells
    if avg_totals_check:
        for row_str in avg_total_rows:
            for cell in ws[f"{row_str}:{row_str}"]:
                cell.style = avg_totals_style.name

# save the workbook
wb.save(filename=excel_filename)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM