在reportlab中添加多行(段落)页脚和页眉
在使用ReportLab这个库的时候,怎么才能在报告的页眉和页脚中放入不仅仅是一行文字的内容呢?我想用canvas.drawString这个方法在onPage函数里绘制它们。但是我找不到办法把像段落这样的内容放进页眉或页脚里。有没有什么好的方法来处理这个问题?有没有办法把段落放到页脚里呢?
5 个回答
4
另一种在所有页面上添加页眉或页脚的方法:可以在构建方法中使用一些参数来实现。
不要使用jochen提供的答案中的框架和模板。在最后一行,使用
doc.build(text, onFirstPage=footer, onLaterPages=footer)
其余的方法和jochen的做法是一样的。
14
Jochen的回答很好,但我觉得不够完整。它适用于页脚,但不适用于页眉,因为Reportlab会把所有的内容绘制在页眉的上面。你需要确保你创建的框架(Frame)的大小不包括页眉占用的空间,这样内容就不会打印在页眉上面。
使用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厘米,以留出空间给页眉。内容会在框架内打印,所以你可以调整框架的大小,以适应不同大小的页眉。
我还发现我通常需要把变量传递到页眉中,所以我使用了一个部分函数并将其分配给onPage,这样就可以把页眉的内容传递进去。这样,你就可以根据页面的内容来设置可变的页眉。
33
在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)