【问题标题】:download PDF with header and footer with Django使用 Django 下载带有页眉和页脚的 PDF
【发布时间】:2018-05-11 13:30:06
【问题描述】:

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

【问题讨论】:

  • weasyprint 是一个很好的实现你想要的东西

标签: django django-views reportlab


【解决方案1】:

扩展BaseDocTemplate 允许您定义包含在PageTemplate 中的FrameFlowables 在框架中使用,因此您的内容可以流到其他页面。页眉和页脚只是放置在框架外部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()

【讨论】:

  • 谢谢@bdoubleu,我成功创建了一个pdf并下载了它,我只是无法处理页脚和页眉。 BaseDocTemplate 是文档而不是画布。如何使用文档而不是画布?
  • 我已经更新了我的答案,展示了如何使用BaseDocTemplate
猜你喜欢
  • 1970-01-01
  • 2019-10-07
  • 2015-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多