Excel alert and problem found when applying conditional formatting to an xlsx file with openpyxl

Question:

My goal is to add conditional formatting to a dataset, more specifically I want to make every row blue where the total profit is less than 70 thousand. When applying the below code on the dataset the Excel gives an alert on opening and the formatting is not applied to the file:

1

The dataset is as follows. ‘A1 : M101’

2

I am using the Pycharm IDE, the latest version of openpyxl (3.0.10), other formatting rules work like number_format and I have reduced the code to the below where the issue shows up. Does anyone know why this issue shows up and how I can fix it or work around it using Python?

import openpyxl
from openpyxl.styles import PatternFill, colors
from openpyxl.styles.differential import DifferentialStyle
from openpyxl.formatting.rule import Rule

work_book = openpyxl.load_workbook('datasets/sales_record.xlsx')
sheet = work_book.active

blue_background = PatternFill(bgColor=colors.BLUE)
diff_style = DifferentialStyle(fill=blue_background)
rule = Rule(type='expression', dxf=diff_style)
rule.formula = ["$1M<70000"]

sheet.conditional_formatting.add(sheet.calculate_dimension(), rule)

work_book.save('workbooks/filename.xlsx')

I have also tried the below but I am unsure if the issue is with the color or some of the other formatting:

a_background = PatternFill(bgColor="FFC7CE", fill_type = "solid")
Asked By: NiggySagan

||

Answers:

Your corrupted workbook is due to the formula

rule.formula = ["$1M<70000"]

It may just be a typo transposing the 1 and M however you don’t want the Header row included anyway so this should be

rule.formula = ["$M2<70000"]

The cell range set would also offset the formatting. It should exclude the Headers as well, so the start of the range should be ‘A2’. Therefore the conditional formatting range should cover ‘A2:MXX’ where XX is the last row.

The changes to your code shown below will then highlight the whole row from Col A to M where the Total_Profit is less than 70,000.
I would also suggest using a different highlight colour than BLUE since it’s too dark to see the text.

import openpyxl
from openpyxl.styles import PatternFill, colors
from openpyxl.styles.differential import DifferentialStyle
from openpyxl.formatting.rule import Rule

work_book = openpyxl.load_workbook('sales_record.xlsx')
sheet = work_book.active

blue_background = PatternFill(bgColor=colors.BLUE)
diff_style = DifferentialStyle(fill=blue_background)
rule = Rule(type='expression', dxf=diff_style)
rule.formula = ["$M2<70000"]

# sheet.conditional_formatting.add(sheet.calculate_dimension(), rule)
cf_range = '$A2:$' + sheet.calculate_dimension().split(':')[1]
sheet.conditional_formatting.add(cf_range, rule)

work_book.save('filename.xlsx')
Answered By: moken