报告实验室中的多行(段落)页脚和页眉

发布于 2024-12-26 01:56:59 字数 140 浏览 2 评论 0原文

在reportlab中拥有页脚和页眉的最佳方法是什么,而不仅仅是一行,可以在onPage函数中使用canvas.drawString绘制。没有找到一种方法将类似段落的内容放入 onPage 函数的页眉/页脚中。处理这个问题的最佳方法是什么?有没有办法将段落放入页脚?

What is a best way to have a footer and header in reportlab, that not just a single line, that can be drawed with canvas.drawString in onPage function. Didn`t find a way to put something like Paragraph into header/footer in onPage function. What is the best way to handle this? Is there a way to put a paragraph into footer ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

提笔落墨 2025-01-02 01:56:59

您可以在 onPage 函数中使用任意绘图命令,因此您可以只绘制一个段落(请参阅 reportlab 用户指南中的第 5.3 节)指南)从你的功能。

这是一个完整的例子:

from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Paragraph

styles = getSampleStyleSheet()
styleN = styles['Normal']
styleH = styles['Heading1']

def footer(canvas, doc):
    canvas.saveState()
    P = Paragraph("This is a multi-line footer.  It goes on every page.  " * 5,
                  styleN)
    w, h = P.wrap(doc.width, doc.bottomMargin)
    P.drawOn(canvas, doc.leftMargin, h)
    canvas.restoreState()

doc = BaseDocTemplate('test.pdf', pagesize=letter)
frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height,
               id='normal')
template = PageTemplate(id='test', frames=frame, onPage=footer)
doc.addPageTemplates([template])

text = []
for i in range(111):
    text.append(Paragraph("This is line %d." % i,
                          styleN))
doc.build(text)

You can use arbitrary drawing commands in the onPage function, so you can just draw a paragraph (see section 5.3 in the reportlab user guide) from your function.

Here is a complete example:

from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Paragraph

styles = getSampleStyleSheet()
styleN = styles['Normal']
styleH = styles['Heading1']

def footer(canvas, doc):
    canvas.saveState()
    P = Paragraph("This is a multi-line footer.  It goes on every page.  " * 5,
                  styleN)
    w, h = P.wrap(doc.width, doc.bottomMargin)
    P.drawOn(canvas, doc.leftMargin, h)
    canvas.restoreState()

doc = BaseDocTemplate('test.pdf', pagesize=letter)
frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height,
               id='normal')
template = PageTemplate(id='test', frames=frame, onPage=footer)
doc.addPageTemplates([template])

text = []
for i in range(111):
    text.append(Paragraph("This is line %d." % i,
                          styleN))
doc.build(text)
甜`诱少女 2025-01-02 01:56:59

Jochen的回答很好,但我发现它不完整。它适用于页脚,但不适用于页眉,因为 Reportlab 会将所有可流动对象绘制在页眉顶部。您需要确保您创建的框架的大小不包括标题占用的空间,以便 Flowabls 不会打印在标题顶部。

使用 jochen 的代码,这里是一个完整的标题示例:

from reportlab.lib.pagesizes import letter, cm
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Paragraph
from functools import partial

styles = getSampleStyleSheet()
styleN = styles['Normal']
styleH = styles['Heading1']

def header(canvas, doc, content):
    canvas.saveState()
    w, h = content.wrap(doc.width, doc.topMargin)
    content.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin - h)
    canvas.restoreState()

doc = BaseDocTemplate('test.pdf', pagesize=letter)
frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height-2*cm, id='normal')
header_content = Paragraph("This is a multi-line header.  It goes on every page.  " * 8, styleN)
template = PageTemplate(id='test', frames=frame, onPage=partial(header, content=header_content))
doc.addPageTemplates([template])

text = []
for i in range(111):
    text.append(Paragraph("This is line %d." % i, styleN))
doc.build(text)

注意框架的减速,它从框架的高度中减去 2 厘米,以便为标题留出空间。 Flowables 将打印在框架内,因此您可以更改框架的大小以适应各种大小的标题。

我还发现我通常需要将变量传递到页眉中,因此我使用了分配给onPage的partial函数,以便可以将页眉的内容传入。这样就可以根据页面的内容拥有一个可变的页眉。

Jochen's answer is great, but I found it incomplete. It works for footers, but not for headers as Reportlab will draw all the flowables on top of the header. You need to be sure the size of the Frame you create excludes the space taken up by the header so flowabls are not printed on top of the header.

Using jochen's code, here is a complete example for headers:

from reportlab.lib.pagesizes import letter, cm
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Paragraph
from functools import partial

styles = getSampleStyleSheet()
styleN = styles['Normal']
styleH = styles['Heading1']

def header(canvas, doc, content):
    canvas.saveState()
    w, h = content.wrap(doc.width, doc.topMargin)
    content.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin - h)
    canvas.restoreState()

doc = BaseDocTemplate('test.pdf', pagesize=letter)
frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height-2*cm, id='normal')
header_content = Paragraph("This is a multi-line header.  It goes on every page.  " * 8, styleN)
template = PageTemplate(id='test', frames=frame, onPage=partial(header, content=header_content))
doc.addPageTemplates([template])

text = []
for i in range(111):
    text.append(Paragraph("This is line %d." % i, styleN))
doc.build(text)

Pay attention to the decleration of the Frame, it subtracts 2 cm from the height of the frame to allow room for the header. The flowables will be printed within the frame so you can change the size of the frame to allow for various sizes of headers.

I also find that I usually need to pass variables into the header, so I used a partial function assigned to onPage so that the content of the header can be passed in. This way you can have a variable header based on the content of the page.

伴随着你 2025-01-02 01:56:59

在所有页面上添加页眉或页脚的其他方法:构建方法有参数可以执行此操作。

不要使用 jochen 答案中的框架和模板。在最后一行中,使用

doc.build(text, onFirstPage=footer, onLaterPages=footer)

其余方法将与 jochen 中的方法相同。

Additional Approach for adding the header or footer on all pages: there are arguments for the build method to do this.

Do not use the frame and template in the answer by jochen. In the last line, use

doc.build(text, onFirstPage=footer, onLaterPages=footer)

the rest of the approach will be the same as from jochen.

他是夢罘是命 2025-01-02 01:56:59

我知道这有点老了,但我遇到过这个问题并且能够解决它。当您的 PDF 中有多个页面并且希望在每一页上都有页脚/页眉时,您必须使用 NextPageTemplate('template_id')。我只编写相关代码,其余部分如上面的 @jochen 示例所示。

就我而言,我使用的是 PageBreak(),我花了一段时间才理解为什么我只在第一页中获取页脚。

from reportlab.platypus import Paragraph, PageBreak, PageTemplate, Frame, NextPageTemplate

frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
template = PageTemplate(id='footer', onPage=footer, frames=[frame])


# add a NextPageTemplate before a PageBreak to have the footer in the next page

text.append(Paragraph('some text', style)),
text.append(NextPageTemplate('footer')), # this will make the footer to be on the next page if exists
text.append(PageBreak())
doc.build(text)

I know this is a bit old but I have encountered this problem and was able to solve it. When you have more than one page in your PDF and want to have the footer/header on every page, You have to use NextPageTemplate('template_id'). I am only writing the relevant code as the rest is shown in @jochen example above.

In my case, I was using PageBreak() and it took me a while to understand why I was only getting the footer in the first page.

from reportlab.platypus import Paragraph, PageBreak, PageTemplate, Frame, NextPageTemplate

frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal')
template = PageTemplate(id='footer', onPage=footer, frames=[frame])


# add a NextPageTemplate before a PageBreak to have the footer in the next page

text.append(Paragraph('some text', style)),
text.append(NextPageTemplate('footer')), # this will make the footer to be on the next page if exists
text.append(PageBreak())
doc.build(text)
猫瑾少女 2025-01-02 01:56:59

我会查看这个答案:

使用 ReportLab 正确添加页码和总页数到 PDF

有一个关于使用 Story 和 SimpleDocTemplate 在 ReportLab 中添加页眉和页脚的精彩示例

I would check out this answer:

Properly add page numbers and total number of pages to PDF using ReportLab

Has an amazing example on adding Header and Footer in ReportLab with Story and SimpleDocTemplate

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文