我想生成一个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中显示namedescriptionpid的值。

最佳答案

正如其他人所提到的,执行此操作的最佳方法是生成模板,然后使用周围的许多库之一将结果转换为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的每个页面上使用。

10-07 19:00
查看更多