2012-01-11 90 views
15

onPage関数でcanvas.drawStringを使用して描画できる1行だけでなく、reportlabにフッターとヘッダーを配置する最適な方法は何ですか? onPage関数のヘッダー/フッターにParagraphのようなものを入れる方法を見つけられませんでした。これを処理する最善の方法は何ですか?段落をフッターに入れる方法はありますか?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

ヨッヘンの答えは素晴らしいですが、私はそれが不完全ました。これは、ヘッダーの上にすべてのフローラベルを描画するので、フッターでは機能しますが、ヘッダーでは機能しません。あなたが作成するフレームのサイズがヘッダによって占められるスペースを除外するようにする必要があります。そうすれば、ヘッダの上にflowablが印刷されなくなります。ヨッヘンのコードを使用して

は、ここにヘッダーの完全な例である:フレームのdeclerationに

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) 

注意を払う、それがヘッダーのスペースを確保するために、フレームの高さから2cmに減算します。 flowableはフレーム内に印刷されるので、さまざまなサイズのヘッダーを使用できるようにフレームのサイズを変更できます。

私は通常、ヘッダーに変数を渡す必要があることがわかります。したがって、ヘッダーの内容を渡すことができるように、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) 
関連する問題