我想生成一个PDF,它将以表格格式显示我的queryset的输出,例如:
query = ModelA.objects.filter(p_id=100)
class ModelA(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=200)
p_id = models.IntegerField()
description = models.TextField()
我需要在生成的PDF中显示
name
,description
和pid
的值。 最佳答案
正如其他人所提到的,执行此操作的最佳方法是生成模板,然后使用周围的许多库之一将结果转换为PDF。此方法为您提供了对模板的通常控制量,例如使用标签。
我使用了前面提到的ReportLab/Pisa设置,但发现它有很大局限性,大多数布局必须使用表来构建,而CSS2规范的许多部分尚未实现。
易于使用的库是wkhtmltopdf,它是WebKit的 headless 发行版。这样的好处是可以像任何Webkit浏览器一样呈现模板,从而使您可以使用特定于Webkit的其他功能,例如WebKit中存在的CSS3规范的一部分。
使用包装器库django-wkhtmltopdf,您可以在 View 中使用render_to_pdf
,而不是通常的Django render_to_response
。
免责声明:我是该图书馆的撰稿人。
更新
该库已转换为CBV,为了方便起见,下面的大多数信息(我将在其中帮助添加一些上下文)现在都在该库中实现。
有关如何实现以下代码块的示例,请参见quickstart文档。如果需要使用更高级的用法,可以将PDFTemplateView
子类化,并添加各种选项,例如filename和margins。
一个示例 View :
from django.shortcuts import render_to_response
from wkhtmltopdf import render_to_pdf
def pdf(request):
context.update({'objects': ModelA.objects.filter(p_id=100)})
kwargs = {}
if request.GET and request.GET.get('as', '') == 'html':
render_to = render_to_response
else:
render_to = render_to_pdf
kwargs.update(dict(
filename='model-a.pdf',
margin_top=0,
margin_right=0,
margin_bottom=0,
margin_left=0))
return render_to('pdf.html', context, **kwargs)
这里的条件语句使您可以将?as = html传递给 View ,以便可以在浏览器中进行开发。目前,这样做有点丑陋,但是有计划在不久的发行版中对此进行修复。
使用此 View ,您可以像往常一样在 View 中循环
objects
的内容,甚至扩展基本模板。我通常为PDF使用不同的样式表,以提高样式的可维护性和可读性,因为您需要对PDF做一些不同的操作,例如,如果希望将页脚块放置在同一位置,请设置最小高度。在此注意事项上,您可以创建页眉和页脚模板,并将它们作为
kwargs
的一部分传递到render_to_pdf中,以在PDF的每个页面上使用。