Winn64
Winn64

Reputation: 33

How do you change from Landscape to Portrait Layout in python ReportLab?

I have a newbie question (should be simple to answer) that has been bugging me for the past day or so and after pouring over all online posts related to reportlab still can't be figured out. All I am trying to do is switch from landscape to portrait orientation in the same document. This will allow me to create a table of features (including links to the pictures of these within the table) and then put in the pictures so they can be linked to.

Here is the code I have come up with so far to facilitate what should be a straight forward process:

from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, landscape
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Frame,
                   Table, TableStyle, NextPageTemplate, PageTemplate, BaseDocTemplate
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.platypus.flowables import Flowable, PageBreak
from pyPdf import PdfFileReader, PdfFileWriter
import glob, os
from reportlab.lib.pagesizes import letter, A4

doc = BaseDocTemplate("M:\GIS Mapping Services\Promotional\Automated Reports\PDF_ReportLab\NextPageExample.pdf",showBoundary=1,pagesize=landscape(letter))
elements = []
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='normal', fontSize=6, leading = 7, alignment=TA_LEFT))

ptemplate = PageTemplate(id='portrait', pagesize=portrait(letter))
elements.append(Paragraph("Table is here.",styles["normal"]))
elements.append(NextPageTemplate('portrait'))
elements.append(PageBreak())
elements.append(Paragraph("Pictures are to be placed here.",styles["normal"]))

doc.build(elements)
del elements

If you have any tips or would like to help me out with this can you please be specific and show me exactly what I am doing wrong or include a working example that goes from start to finish without any coding missing.

Thank you in advance for your help,

Winn

Upvotes: 3

Views: 7149

Answers (2)

Sina Khelil
Sina Khelil

Reputation: 1991

You can simplify the above further. There is no need for the two additional functions to set the rotated canvas:

    p_frame = Frame(0.5 * inch, 0.5 * inch, 7.5 * inch, 10 * inch,
                   leftPadding=0, rightPadding=0,
                   topPadding=0, bottomPadding=0,
                   id='portrait_frame')

    l_frame = Frame(0.5 * inch, 0.5 * inch, 10 * inch, 7.5 * inch,
                    leftPadding=0, rightPadding=0,
                    topPadding=0, bottomPadding=0,
                    id='landscape_frame')

    portrait_tmpl = PageTemplate(id='portrait_tmpl', frames=[p_frame], pagesize=letter)
    landscape_tmpl = PageTemplate(id='landscape_tmpl', frames=[l_frame], pagesize=landscape(letter))

It is a bit more maintainable. Although, I have not found a way around the setting two separate frames.

The frame that is in the answer did not work for me on rotation.

Upvotes: 4

Kyle Heuton
Kyle Heuton

Reputation: 9768

Here is a hack, based on the answer I found here.

from reportlab.lib.enums import TA_LEFT, TA_RIGHT, TA_CENTER, TA_JUSTIFY
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, landscape
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Frame,Table, TableStyle, NextPageTemplate, PageTemplate, BaseDocTemplate
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.platypus.flowables import Flowable, PageBreak
from pyPdf import PdfFileReader, PdfFileWriter
import glob, os
from reportlab.lib.pagesizes import letter, A4

def make_portrait(canvas,doc):
    canvas.setPageSize(letter)

def make_landscape(canvas,doc):
    canvas.setPageSize(landscape(letter))

doc = BaseDocTemplate("NextPageExample.pdf",showBoundary=1)
elements = []
styles = getSampleStyleSheet()
styles.add(ParagraphStyle(name='normal', fontSize=6, leading = 7, alignment=TA_LEFT))


frame1 = Frame(doc.leftMargin, doc.height-5*inch,
                doc.width, 5*inch,
                leftPadding = 0, rightPadding = 0,
                topPadding = 0, bottomPadding = 0,
                id='frame1')

ptemplate = PageTemplate(id='portrait',frames =[frame1], onPage=make_portrait)
ltemplate = PageTemplate(id='landscape',frames =[frame1], onPage=make_landscape)
doc.addPageTemplates([ptemplate, ltemplate])
elements.append(Paragraph("Table is here.",styles["normal"]))
elements.append(NextPageTemplate('landscape'))
elements.append(PageBreak())
elements.append(Paragraph("Pictures are to be placed here.",styles["normal"]))

doc.build(elements)
del elements

When working with platypus, the easiest way I've found to manipulate the canvas is via the onPage setting of a PageTemplate that lets you implement the non-flowing part of the text. Here, before anything is drawn on either the landscape or portrait template, the canvas is re-sized to the desired size.

Upvotes: 7

Related Questions