Python openpyxl空白单元格条件格式化

Python openpyxl空白单元格条件格式化,python,excel,openpyxl,conditional-formatting,Python,Excel,Openpyxl,Conditional Formatting,我对空白单元格的格式有问题。 我的代码是 import setting_prices import pandas as pd from openpyxl import Workbook, load_workbook from openpyxl.styles import Color, PatternFill, Font, Border from openpyxl.styles.differential import DifferentialStyle from openpyxl.formatti

我对空白单元格的格式有问题。 我的代码是

import setting_prices
import pandas as pd
from openpyxl import Workbook, load_workbook
from openpyxl.styles import Color, PatternFill, Font, Border
from openpyxl.styles.differential import DifferentialStyle
from openpyxl.formatting.rule import ColorScaleRule, CellIsRule, FormulaRule
import os
from datetime import datetime


def load_file_apply_format():

    wb = load_workbook(filename)
    writer = pd.ExcelWriter(filename, engine='openpyxl')
    writer.book = wb
    prices.to_excel(writer, sheet_name=today_as_str)
    ws = wb[today_as_str]

    redFill = PatternFill(start_color='EE1111',
                              end_color='EE1111',
                              fill_type='solid')
    # whiteFill = PatternFill(start_color='FFFFFF',
    #                           end_color='FFFFFF',
    #                           fill_type='solid')


    ws.conditional_formatting.add('B2:H99',
                                      CellIsRule(operator='lessThan',
                                                 formula=['$I2'],
                                                 stopIfTrue=False, fill=redFill))
    

    writer.save()


prices = setting_prices.df

today_as_str = datetime.strftime(datetime.now(), ' %d_%m_%y')
desktop_path = os.path.expanduser("~/Desktop")

filename = 'price_check.xlsx'


if os.path.exists(filename):
    load_file_apply_format()
else:
    prices.to_excel(filename, sheet_name=today_as_str)
    load_file_apply_format()

我的公式运行得很好,但excel将空白单元格视为0,因此它们总是小于列I,并对其进行格式化。我想跳过空白单元格,或将其格式化为常规单元格

我尝试了论坛上几乎所有的建议,但似乎我无法解决它

请给我一些建议

@格雷格回答使用:

   ws.conditional_formatting.add('B2:H99',
                                  CellIsRule(operator='between',
                                             formula=['1', '$I2'],
                                             stopIfTrue=False, fill=redFill))

结果将==的单元格格式化为我要避免的“I”列。如果“I”列中的单元格为空,“between”是将格式设置为所有空白单元格

例如: productA的所有单元格都必须采用默认格式,因为它们等于“I”列中的单元格。 对于
productB
而言,唯一格式化的单元格必须是
G3
,因为它比
I3
低。
productC
的所有单元格必须为默认格式,因为I中的单元格为空


我想,如果我对Lessten使用格式代码,对空白单元格使用另一个公式,就可以了。但是我没能让它工作。

我用try/error方法解决了我的问题。 我将在这里发布我的解决方案,希望有人会发现它有用。 最终结果由以下方面得出:

  • 将行中的所有单元格放置到列表中
  • 将列表中的所有值与所需值进行比较
  • 如果单元格较低->应用格式化
  • 最后的代码是:

    import ...
    
    
    
    def apply_format_to_cell(cell):
    
        """
        Set background and font color For the current cell
        """
    
        ft = Font(color="FF0000")
        fill_black = PatternFill(bgColor="FFC7CE", fill_type="solid")
    
        cell.font = ft
        cell.fill = fill_black
    
        return cell
    
    
    def open_existing_file(file_name):
        """
        open an existing file to format cell
        which is meeting a condition
        """
    
        wb = load_workbook(file_name)
        writer = pd.ExcelWriter(file_name, engine='openpyxl')
        writer.book = wb
        prices.to_excel(writer, sheet_name=today_as_str)
        ws = wb[today_as_str]
    
        for row in ws.iter_rows(2, ws.max_row, 2):
            """
            1st parameter says to start from 2 row 
            2nd parameter stands for -> till the last row with data. 
            3th parameter says start from 2 COLUMN. 
                In this case this is B2
            """
            cells_in_row = []  # making a list of cells which we will compare
            for cells in row:
                cells_in_row.append(cells)
            for cell in cells_in_row:
                if cell.value is not None and type(cell.value) is not str \
                        and cells_in_row[-1].value is not None and type(cells_in_row[-1].value) is not str:
                    """
                    Checks if the cell value is not Empty or str ( '' ).
                    """
    
                    if cell.value < cells_in_row[-1].value:
                        apply_format_to_cell(cell)
        if wb[f'{today_as_str + "1"}']:
            """
            For the first run only!
            Because: prices.to_excel(writer, sheet_name=today_as_str) will make again sheet
            with the same name -> Excel will put '1' at the end of name 'Sheet_name' > 'Sheet_name1'
            This if will delete this unwanted sheet!
            """
            del wb[f'{today_as_str + "1"}']
    
        writer.save()
    
    
    prices = setting_prices.df  # import df with prices
    
    today_as_str = datetime.strftime(datetime.now(), ' %d_%m_%y')
    desktop_path = os.path.expanduser("~/Desktop")
    
    filename = 'price_check.xlsx'
    
    
    if os.path.exists(filename):
        open_existing_file(filename)
    else:
        prices.to_excel(filename, sheet_name=today_as_str)
        open_existing_file(filename)
    
    
    导入。。。
    def将_格式_应用于_单元格(单元格):
    """
    设置当前单元格的背景和字体颜色
    """
    ft=Font(color=“FF0000”)
    填充黑色=图案填充(bgColor=“FFC7CE”,填充类型=“实心”)
    cell.font=ft
    cell.fill=fill\u黑色
    返回单元
    def open_现有_文件(文件名):
    """
    打开现有文件以格式化单元格
    这是符合条件的
    """
    wb=加载工作簿(文件名)
    writer=pd.ExcelWriter(文件名,engine='openpyxl')
    writer.book=wb
    prices.to_excel(书写者,工作表名称=今天)
    ws=wb[今天作为未来]
    对于ws.iter_行中的行(2,ws.max_行,2):
    """
    第一个参数表示从第2行开始
    第二个参数表示->直到最后一行有数据。
    第3个参数表示从2列开始。
    在这种情况下,这是B2
    """
    单元格_in_row=[]#列出我们将要比较的单元格
    对于行中的单元格:
    行中的单元格。追加(单元格)
    对于\u行中的单元格中的单元格:
    如果cell.value不是None并且type(cell.value)不是str\
    和第_行[-1]中的第_个单元格。值不是None,类型(第_行[-1]中的第_个单元格)。值不是str:
    """
    检查单元格值是否为空或str(“”)。
    """
    如果cell.value<行[-1]中的cells\u,则值:
    将\u格式\u应用于\u单元格(单元格)
    如果wb[f'{today_as_str+“1”}']:
    """
    仅限第一次跑步!
    因为:prices.to_excel(writer,sheet_name=today_as_str)将再次制作工作表
    使用相同的名称->Excel将把“1”放在名称“Sheet\u name”>“Sheet\u name1”的末尾
    此if将删除此不需要的工作表!
    """
    del wb[f'{today_as_str+“1”}']
    writer.save()
    价格=设置_prices.df#使用价格导入df
    今天\u as\u str=datetime.strftime(datetime.now(),“%d\u%m\u%y”)
    桌面\u path=os.path.expanduser(“~/desktop”)
    文件名='price_check.xlsx'
    如果os.path.存在(文件名):
    打开现有文件(文件名)
    其他:
    prices.to_excel(文件名,sheet_name=today_as_str)
    打开现有文件(文件名)
    
    最终结果示例: