2012-01-11 565 views
15

什麼是在reportlab中有一個頁腳和頁眉的最佳方式,不僅僅是一行,可以在onPage函數中使用canvas.drawString進行繪製。沒有找到一種方法來將段落等內容放入onPage函數的頁眉/頁腳中。處理這個問題的最好方法是什麼?有沒有辦法將一個段落放入頁腳?reportlab中的多行(段落)頁腳和頁眉

回答

23

您可以在onPage函數中使用任意繪圖命令,因此您可以從函數中繪製一段(參見reportlab user guide中的第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) 
8

約亨的答案是偉大的,但我發現它不完整的。它適用於頁腳,但不適用於頁眉,因爲Reportlab將在頁眉頂部繪製所有流動頁面。您需要確保您創建的框架的大小不包括標題佔用的空間,因此流程標籤不會打印在標題頂部。

使用約亨的代碼,這裏是頭一個完整的例子:

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) 

注重框架的decleration,它減去從幀的高2釐米留出空間的標題。流動件將打印在框架內,因此您可以更改框架的尺寸以適應各種尺寸的頁眉。

我還發現我通常需要將變量傳遞到頭文件中,所以我使用了分配給onPage的部分函數,​​以便可以傳入頭文件的內容。這樣您就可以擁有一個基於頁面的內容。

0

我知道這是有點舊,但我遇到了這個問題,並能夠解決它。當您的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)