如何在Python ReportLab中从横向布局切换到纵向布局?

3 投票
2 回答
6900 浏览
提问于 2025-04-17 18:44

我有一个新手问题(应该很简单就能回答),这让我困扰了大约一天。尽管我查阅了所有与reportlab相关的在线帖子,还是没能搞明白。我想做的就是在同一个文档中从横向切换到纵向。这将让我创建一个功能表(包括指向这些功能图片的链接),然后把图片放进去,以便可以链接到它们。

这是我目前为这个看似简单的过程写的代码:

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

如果你有任何建议,或者想帮我解决这个问题,请具体说明,告诉我我到底哪里做错了,或者给我一个完整的示例,从头到尾没有缺失的代码。

提前感谢你的帮助,

Winn

2 个回答

4

你可以进一步简化上面的内容。其实不需要那两个额外的函数来设置旋转的画布:

    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))

这样做会稍微好维护一些。不过,我还没有找到不需要设置两个单独框架的方法。

答案中的那个框架在旋转时对我来说不太管用。

7

这里有个小技巧,灵感来自我在这里找到的答案。

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

在使用platypus的时候,我发现最简单的方法是通过PageTemplate的onPage设置来调整画布,这样可以处理文本的非流动部分。在这里,在横向或纵向模板上绘制任何东西之前,画布会被调整到想要的大小。

撰写回答