Reputation: 1400
The code below creates a nice test table with 99 rows of data and a header that gets repeated at each page break. The table is quite narrow so I am trying to figure out how to make it split so that it has rows 1-37 on the left hand side of the first page, rows 38-74 on the right hand side of the first page, and rows 75-99 on the left hand side of the second page. I've called this "splitting a table across a page" but there may be a better name for what I am trying to do so I hope I have described it accurately.
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 and start data list
column1Heading = "COL ONE"
column2Heading = "COL TWO"
# Assemble data for each column using simple loop to append it into data list
data = [[column1Heading,column2Heading]]
for i in range(1,100):
data.append(["Col 1 Row " + str(i),"Col 2 Row " + str(i)])
tableThatSplitsOverPages = Table(data, [2.5 * cm, 2.5 * cm], repeatRows=1)
tableThatSplitsOverPages.hAlign = 'LEFT'
tblStyle = TableStyle([('TEXTCOLOR',(0,0),(-1,-1),colors.black),
('VALIGN',(0,0),(-1,-1),'TOP'),
('LINEBELOW',(0,0),(-1,-1),1,colors.black),
('BOX',(0,0),(-1,-1),1,colors.black),
('BOX',(0,0),(0,-1),1,colors.black)])
tblStyle.add('BACKGROUND',(0,0),(1,0),colors.lightblue)
tblStyle.add('BACKGROUND',(0,1),(-1,-1),colors.white)
tableThatSplitsOverPages.setStyle(tblStyle)
elements.append(tableThatSplitsOverPages)
doc.build(elements)
Upvotes: 2
Views: 6558
Reputation: 6107
If you know the exact number of rows on the page you can use this function to simulate two columns. That way the the table still automatically flows over multiple pages and you don't have to worry about PageTemplates.
def columnize(data, interval):
ret = []
for i in range(0, len(data), interval * 2):
for j in range(min(interval, len(data) - i)):
ret.append(data[i + j] + (data[i + j + interval] if i + j + interval < len(data) else []))
return ret
Use in your example:
data = columnize(data, 75)
tableThatSplitsOverPages = Table(data, [2.5 * cm, 2.5 * cm], repeatRows=1)
Upvotes: 3
Reputation: 8068
You will need to use PageTemplates to accomplish this by creating a PageTemplate that has multiple Frames that will allow you to specify content areas to draw the document within the page. This unfortunately means abandoning SimpleDocTemplate and instead using BaseDocTemplate and supplying your own PageTemplates (as well as other things if you want them).
Upvotes: 3