pythonreportlabplatypus

Moving to the next Frame in ReportLab


In ReportLab, I have a Page Template made out of 2 vertical Frames. What I am trying to achieve here is - after putting some dynamic text onto the page (first frame), I would like to go to the top of the 2nd frame.

I've tried to achieve this by calculating the height of the text objects from the 1st frame and then inserting a Spacer with height equal to (doc.height - the weight of the text objects from the 1st frame). However, this is not working. This is the simplified code and its output.

   from reportlab.lib.pagesizes import A4, landscape
   from reportlab.lib.units import inch
   from reportlab.lib.styles import ParagraphStyle

   from reportlab.platypus import *

   if __name__ == "__main__":

       style_1 = ParagraphStyle(name='Stylo',
                              fontName='Helvetica',
                              fontSize=20,
                              leading=12)

       doc = BaseDocTemplate('test_spacer.pdf', showBoundary=1, 
                             pagesize=landscape(A4), topMargin=30,
                           bottomMargin=30,
                           leftMargin=30, rightMargin=30)

      frameCount = 2
      frameWidth = (doc.width) / frameCount
      frameHeight = doc.height - .05 * inch

      frames = []
      column = Frame(doc.leftMargin, doc.bottomMargin, 200, doc.height - .05* inch)
      frames.append(column)
      column = Frame(doc.leftMargin + 200, doc.bottomMargin, frameWidth - 200, doc.height - .05 * inch)
      frames.append(column)

      doc.addPageTemplates([PageTemplate(id='framess', frames=frames)])

      story = []

      for i, x in enumerate(['A', 'B', 'C']):

          text = x*10*(i+1)

          p1 = Paragraph(text, style_1)
          w, h1 = p1.wrap(200, doc.height)

          p2 = Paragraph(text*2, style_1)
          w, h2 = p2.wrap(200, doc.height)

          story.append(p1)
          story.append(p2)

          spac_height = ((doc.height) - (h1 + h2))
          story.append(Spacer(width=0, height=spac_height))

          story.append(Paragraph('This should be on the top of the 2nd Frame!' + x, style_1))

          story.append(PageBreak())

      doc.build(story)

enter image description here

Does anyone know what I am doing wrong here? Thanks!


Solution

  • I suggest you try using FrameBreak instead of a Spacer, as I think the break is a better solution to your issue.

    Here is a modified version fo your code to show the result:

    import random
    from reportlab.lib.pagesizes import A4, landscape
    from reportlab.lib.styles import ParagraphStyle
    from reportlab.lib.units import inch
    from reportlab.platypus import (
        BaseDocTemplate, PageTemplate, PageBreak, Frame, FrameBreak, Spacer, Paragraph,
    )
    
    
    if __name__ == "__main__":
        style_1 = ParagraphStyle(
            name='Stylo',
            fontName='Helvetica',
            fontSize=10,
            leading=12)
        doc = BaseDocTemplate(
            'test_spacer.pdf',
            showBoundary=1,
            pagesize=landscape(A4),
            topMargin=1*inch,
            bottomMargin=1*inch,
            leftMargin=1*inch,
            rightMargin=1*inch)
    
        frameCount = 2
        frameWidth = doc.width / frameCount
        frameHeight = doc.height - 0.05*inch
    
        frame_list = [
            Frame(
                x1=doc.leftMargin,
                y1=doc.bottomMargin,
                width=frameWidth,
                height=frameHeight),
            Frame(
                x1=doc.leftMargin + frameWidth,
                y1=doc.bottomMargin,
                width=frameWidth,
                height=frameHeight),
        ]
        doc.addPageTemplates([PageTemplate(id='frames', frames=frame_list), ])
    
        story = []
        for i, x in enumerate(['A', 'B', 'C']):
            # add text in first frame
            for _ in range(3):
                story.append(
                    Paragraph(
                        x * random.randint(50, 100),
                        style_1))
    
            # jump to next frame
            story.append(FrameBreak())
    
            # add text in second frame
            story.append(
                Paragraph(
                    'This should be on the top of the 2nd Frame! ' + x,
                    style_1))
    
            story.append(PageBreak())
    
        doc.build(story)
    

    It gives this output (this image only shows the first 2 pages):

    enter image description here