Search code examples
pythondataframeif-statementfpdf

Python FPDF fill color of a cell based on an IF statement


Team,

How do I change the cell background color of a table. For example, I want to change the cell background of column B items if it is "No" using FPDF and IF statement or other methods. That is if a No is in the cell, the "No" cell should be colored.

Column A Column B
Yes No
Yes No
    if df.Column B.any() == "No":
        pdf.set_fill_color(193, 229, 252)
        pdf.cell(30, 10, 'No', 1, 1, 'C', True)

But it did not work.


Solution

  • Besides the syntax error in df.Column B, df["Column B"].any() will always returns True.

    You can try using iterrows from :

    from fpdf import FPDF
    
    pdf = FPDF()
    pdf.add_page()
    
    pdf.set_fill_color(255, 255, 255) #make a white-bg
    pdf.set_font("Arial", "B", 12) # <-- ajudst here if needed
    for col in df.columns:
        pdf.cell(30, 10, col, 1, 0, "C", 1)
    pdf.ln(10) #a newline
    
    for _, row in df.iterrows():
        pdf.set_font("Arial", "", 10)  # <-- ajudst here if needed
        pdf.cell(30, 10, row["Column A"], 1, 0, "C")
    
        if row["Column B"] == "No":
            pdf.set_fill_color(193, 229, 252) #make a blue-bg
            pdf.cell(30, 10, row["Column B"], 1, 0, "C", 1)
        else:
            pdf.cell(30, 10, row["Column B"], 1, 0, "C")
    
        pdf.ln(10) #a newline
    
    pdf.output("output.pdf", "F")
    

    Output (.pdf) :

    enter image description here

    Equivalent with Styler (in Jupyter) :

    (
        df.style
         .applymap(lambda x: "background-color: #C1E5FC"
                   if x == "No" else "", subset=["Column B"])
    )
    

    enter image description here

    UPDATE :

    Actually I have four columns. There are 2 columns before column A. How do I re-write for pdf.cell(30, 10, row["Column A"], 1) for each column preceeding column B ?

    for _, row in df.iterrows():
        pdf.set_font("Arial", "", 10)
        pdf.cell(30, 10, row["Column 1"], 1, 0, "C") # <-- add this line
        pdf.cell(30, 10, row["Column 2"], 1, 0, "C") # <-- add this line
        pdf.cell(30, 10, row["Column A"], 1, 0, "C")
    
        if row["Column B"] == "No":
            pdf.set_fill_color(193, 229, 252) #make a blue-bg
            pdf.cell(30, 10, row["Column B"], 1, 0, "C", 1)
        else:
            pdf.cell(30, 10, row["Column B"], 1, 0, "C")
    
        pdf.ln(10) #a newline
    
    pdf.output("output.pdf", "F")
    

    Output :

    enter image description here

    Input used :

      Column 1 Column 2 Column A Column B
    0        A        X      foo      Yes
    1        B        Y      bar       No
    2        C        Z      baz      Yes