How to Repeat Table Column Headings over Page Breaks in PDF output from ReportLab

PolyGeo picture PolyGeo · Feb 14, 2012 · Viewed 15.4k times · Source

I'm using ReportLab to write tables in PDF documents and am very pleased with the results (despite not having a total grasp on flowables just yet).

However, I have not been able to figure out how to make a table that spans a page break have its column headings repeated.

The code below creates a test.pdf in C:\Temp that has a heading row followed by 99 rows of data.

The heading row looks great on the first page but I would like that to repeat at the top of the second and third pages.

I'm keen to hear of any approaches that have been used to accomplish that using the SimpleDocTemplate.

from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Frame, Spacer
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.pagesizes import A3, A4, landscape, portrait
from reportlab.lib.styles import ParagraphStyle, getSampleStyleSheet
from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.pdfgen import canvas

pdfReportPages = "C:\\Temp\\test.pdf"
doc = SimpleDocTemplate(pdfReportPages, pagesize=A4)

# container for the "Flowable" objects
elements = []
styles=getSampleStyleSheet()
styleN = styles["Normal"]

# Make heading for each column
column1Heading = Paragraph("<para align=center>COLUMN ONE HEADING</para>",styles['Normal'])
column2Heading = Paragraph("<para align=center>COLUMN TWO HEADING</para>",styles['Normal'])
row_array = [column1Heading,column2Heading]
tableHeading = [row_array]
tH = Table(tableHeading, [6 * cm, 6 * cm])            # These are the column widths for the headings on the table
tH.hAlign = 'LEFT'
tblStyle = TableStyle([('TEXTCOLOR',(0,0),(-1,-1),colors.black),
                       ('VALIGN',(0,0),(-1,-1),'TOP'),
                       ('BOX',(0,0),(-1,-1),1,colors.black),
                       ('BOX',(0,0),(0,-1),1,colors.black)])
tblStyle.add('BACKGROUND',(0,0),(-1,-1),colors.lightblue)
tH.setStyle(tblStyle)
elements.append(tH)

# Assemble rows of data for each column
for i in range(1,100):
    column1Data = Paragraph("<para align=center> " + "Row " + str(i) + " Column 1 Data" + "</font> </para>",styles['Normal'])
    column2Data = Paragraph("<para align=center> " + "Row " + str(i) + " Column 2 Data" + "</font> </para>",styles['Normal'])
    row_array = [column1Data,column2Data]
    tableRow = [row_array]
    tR=Table(tableRow, [6 * cm, 6 * cm])   
    tR.hAlign = 'LEFT'
    tR.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),colors.white),
                            ('TEXTCOLOR',(0,0),(-1,-1),colors.black),
                            ('VALIGN',(0,0),(-1,-1),'TOP'),
                            ('BOX',(0,0),(-1,-1),1,colors.black),
                            ('BOX',(0,0),(0,-1),1,colors.black)]))
    elements.append(tR)
    del tR

elements.append(Spacer(1, 0.3 * cm))

doc.build(elements)

Answer

G Gordon Worley III picture G Gordon Worley III · Feb 14, 2012

From the documentation (yes, I know, but it's sometimes hard to locate this stuff in the manual):

The repeatRows argument specifies the number of leading rows that should be repeated when the Table is asked to split itself.

So when you create the table, this is one of the arguments you can pass, and it will turn the first n rows into header rows that repeat. You'll find this part of the text on page 77, but the section relating to creating a Table starts on page 76.

http://www.reportlab.com/docs/reportlab-userguide.pdf