首页 > 解决方案 > 使用 Django 下载带有页眉和页脚的 PDF

问题描述

我刚开始使用 Django,我想创建一个按钮来启动带有页眉和页脚的 PDF 下载。对于 PDF,我使用 Reportlab。在 Django 文档中,他们说要使用 Canvas 对象,但我无法使用画布添加页脚和页眉。谁能给我一段代码,它将从 Django 中的视图返回响应,并带有页脚和页眉的 PDF 下载?谢谢你!

标签: djangodjango-viewsreportlab

解决方案


扩展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()

推荐阅读