4

I've created a table using ReportLab. I would like to conditionally color the cells, depending on their contents (in my case, I want negative numbers to be red). To be clear, I have the conditional code working, I can't figure out how to add color. What I've tried:

  • using the <font color="..."> tag. Instead, the tags is included verbatim in the output.
  • wrapping each cell in Paragraph(...) (suggested in this answer). In this case, the cell text is linewrapped after each letter.
  • wrapping the table in Paragraph(...). In this case, reportlab errors out (I believe the resulting error was TypeError: split() missing required positional argument: 'availHeight')
  • I found reportlab.platypus.tables.CellStyle in the reportlab source code, but can't figure out make use of it. Google turns up nothing useful and it's not mentioned in the reportlab documentation.
  • I guess TableStyle(...) rules could be used, but the cells aren't in a predetermined position within the table (which is what all the examples assume).

Help appreciated!

MinchinWeb
  • 631
  • 1
  • 9
  • 18

1 Answers1

8

Using TableStyle() would be an acceptable solution. You could loop through the data and add a style command when the condition is met.

Here is an example:

import random
from reportlab.lib.pagesizes import letter
from reportlab.lib.colors import red
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle

# Generate random data with positive and negative values as list of lists.
data = []
for _ in range(20):
    data.append(random.sample(range(-10, 10), 5))
table_style = TableStyle([('ALIGN', (0, 0), (-1, -1), 'RIGHT')])
# Loop through list of lists creating styles for cells with negative value.
for row, values, in enumerate(data):
    for column, value in enumerate(values):
        if value < 0:
            table_style.add('TEXTCOLOR', (column, row), (column, row), red)

table = Table(data)
table.setStyle(table_style)
pdf = SimpleDocTemplate('example.pdf', pagesize=letter)
pdf.build([table])
Adam Moller
  • 903
  • 8
  • 11