django - 使用 Django 下载带有页眉和页脚的 PDF
问题描述
我刚开始使用 Django,我想创建一个按钮来启动带有页眉和页脚的 PDF 下载。对于 PDF,我使用 Reportlab。在 Django 文档中,他们说要使用 Canvas 对象,但我无法使用画布添加页脚和页眉。谁能给我一段代码,它将从 Django 中的视图返回响应,并带有页脚和页眉的 PDF 下载?谢谢你!
解决方案
扩展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()
推荐阅读
- html - 当信息来自 php 站点上的 mysql 时,有没有办法进行名称换行?
- fancybox-3 - Fancybox3 位置标题正下方图像
- authentication - 通过 curl 在 wso2 中进行用户身份验证
- ruby-on-rails - Presenter 中的模板路径问题 (ActionView::Template::Error (Missing partial...)
- javascript - 如何根据边的数组对象内的数据选择边?
- azure-data-explorer - Azure 数据资源管理器是否会在排队的引入中自动处理引入的瞬时故障?
- dicom - 有没有一种简单的方法可以找到 DICOM 标签的类型?
- javascript - 我可以更改/覆盖 window.getSelection() 的定义吗?
- asp.net - 如何修复 C# asp.net 中的目录遍历安全漏洞?
- python - 如果任何列返回匹配项,则在将记录分组在一起的多个列上使用 GROUP BY