I am trying to refactor a script that generates several four page pdfs and abstract a very long >400 line script into several methods. I have methods that draw each footer and create each of the four pages. The problem is that when I call doc.addPageTemplates()
only works when given a single template. If I try to add more than one it creates a separate page for each element.
For example, this method generates the second page:
def page_two():
f_title = Frame(width - doc.rightMargin - graph_width + 0.2 * inch,
doc.bottomMargin + footer_height + 7,
graph_width, cap_height,
leftPadding=0, rightPadding=0,
topPadding=0, bottomPadding=0,
id='title')
f_graph = Frame(width - doc.rightMargin - graph_width,
doc.bottomMargin + footer_height,
graph_width, cap_height,
leftPadding=0, rightPadding=0,
topPadding=0, bottomPadding=0,
id='graph')
post_header_space = 3
elements.append(Paragraph("LOREM IPSUM DOLOR SIT AMET"
, styles['body_heading']))
elements.append(Spacer(1, post_header_space))
yld_para = "lorem ipsum dolor sit amet consectetur adipiscing elit"
elements.append(Paragraph(yld_para
, styles['body_text']))
elements.append(FrameBreak())
elements.append(Spacer(1, 40))
elements.append(Paragraph("%s YLDs by cause and age 2010" % country_name
, styles['fig_cap']))
elements.append(FrameBreak())
elements.append(Paragraph("LOREM IPSUM DOLOR SIT AMET"
, styles['body_heading']))
elements.append(Spacer(1, post_header_space))
elements.append(FrameBreak())
elements.append(Spacer(1, 10))
elements.append(FrameBreak())
elements.append(PageBreak())
return PageTemplate(id='SecondPage', frames=[f_title, f_graph], onPage=foot_dash_2)
and this generates its footer:
def foot_dash_2(canvas, doc):
arrow_scale = 1.0
canvas.translate(-.23 * inch, -9.9 * inch)
canvas.scale(arrow_scale, arrow_scale)
canvas.restoreState()
canvas.scale(arrow_scale, arrow_scale)
canvas.restoreState()
arrow_scale = 0.55
canvas.translate(doc.leftMargin + 126.0 + 7.5 * inch, 31.0 - 0.2 * inch)
canvas.scale(arrow_scale, arrow_scale)
canvas.rotate(90)
canvas.restoreState()
canvas.saveState()
canvas.setLineWidth(0.4)
canvas.setDash(0.4, 5)
line_height = 329.8 + 72.0 + dash_buffer / 2
canvas.line(doc.leftMargin, line_height, width - doc.rightMargin, line_height)
canvas.restoreState()
canvas.saveState()
canvas.setFont('Helvetica', 22)
canvas.setFillColorCMYK(81 / 100.0, 45 / 100.0, 53 / 100.0, 23 / 100.0) # choose fill colour
canvas.rect(0, doc.bottomMargin - 3, width, 15, fill=1, stroke=0)
left_foot = Paragraph("http://www.example.cp,",
styles['left_footer_1'])
w, h = left_foot.wrap(doc.width, doc.bottomMargin)
left_foot.drawOn(canvas, doc.leftMargin, doc.bottomMargin - foot_displace)
right_foot = Paragraph(" %s | Text | page %d" % (country_name, 2),
styles['right_footer_1'])
w, h = right_foot.wrap(doc.width, doc.bottomMargin)
right_foot.drawOn(canvas, doc.rightMargin, doc.bottomMargin - foot_displace)
canvas.restoreState()
# Y axis label
canvas.saveState()
canvas.setFont('OpenSans', 7)
canvas.setFillColorRGB(0, 0, 0, 1)
canvas.rotate(90)
canvas.drawString(2 * inch, -3.2 * inch, "Percent change 1990-2010")
canvas.restoreState()
As you can see the page_two()
method adds elements to an elements list and returns a PageTemplate object.
I generate the PDF like this:
doc.addPageTemplates([page_two()])
doc.build(elements)
This works. However, if I want to add multiple page templates, the only correct page is the first one and then reportlab generates a page for every individual element:
doc.addPageTemplates([page_one(), page_two(), page_three(), page_four()])
doc.build(elements)
How can I stop this from happening and generate complete pages? All the other page methods and footer methods are variations of the ones posted.
This is not clear in the reportlab docs, but if when using simple doc template you need to add a NextPageTemplate in order to start new Page Object to contain all frames. So in this case you would just add elements.append(NextPageTemplate('SecondPage'))
to the end of the method that generates the first page.