Расширение BaseDocTemplate
позволяет вам определить Frame
, содержащийся в PageTemplate
. Flowables
используются во фрейме, чтобы ваш контент мог перетекать на другие страницы. Верхний и нижний колонтитулы - это просто строки текста, помещенные на Canvas
вне рамки. saveState()
и restoreState()
должны использоваться при определении верхнего и нижнего колонтитула, чтобы они повторялись на каждой странице вашего pdf.
class HeaderFooterTemplate(BaseDocTemplate):
def __init__(self, filename, **kwargs):
self.report_title = kwargs['report_title']
self.pagesize = kwargs['pagesize']
BaseDocTemplate.__init__(self, filename, **kwargs)
main_frame = Frame(
0, 0, self.pagesize[0], self.pagesize[1], topPadding=25, bottomPadding=18, id='main_frame')
template = PageTemplate(id='frame', frames=[main_frame], onPage=self.header_footer)
self.addPageTemplates([template])
def header_footer(self, canv, doc):
canv.saveState()
canv.setPageSize(doc.pagesize)
canv.setTitle(doc.title)
# header
canv.drawCentredString(doc.pagesize[0] / 2, doc.pagesize[1] - 15, self.report_title)
# footer
date_printed = 'Date Printed: ' + dateformat.format(timezone.localtime(timezone.now()), 'Y-m-d f A')
footer_date = canv.beginText(0, 2)
footer_date.textLine(date_printed)
canv.drawText(footer_date)
canv.restoreState()
class PdfTest:
def __init__(self):
self.buffer = BytesIO()
self.pagesize = letter
self.story = []
def build_pdf(self, filename):
"""
Get the value of the BytesIO buffer and write it to the response.
:param filename: name of the file when downloading
"""
pdf = self.buffer.getvalue()
self.buffer.close()
if pdf:
response = HttpResponse(pdf, content_type='application/pdf')
content = 'inline; filename="%s"' % filename
response['Content-Disposition'] = content
return response
def draw(self):
style = styles["Normal"]
for i in range(100):
bogustext = ("This is Paragraph number %s. " % i) *20
p = Paragraph(bogustext, style)
self.story.append(p)
self.story.append(Spacer(1,0.2*inch))
doc = HeaderFooterTemplate(self.buffer, pagesize=self.pagesize, report_title='Test Header Footer PDF')
doc.build(self.story)
return self.build_pdf('test.pdf')
class PdfView(View):
def get(self, request):
pdf = PdfTest()
return pdf.draw()