django pdf export

时间:2011-10-19 12:11:03

标签: django pdf pdf-generation django-views

我想生成一个PDF,它将以表格格式显示我的查询集的输出,例如:

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的值。

4 个答案:

答案 0 :(得分:9)

正如其他人所提到的,最好的方法是生成一个模板,然后使用众多库中的一个将结果转换为PDF。此方法为您提供了对模板的常规控制,例如使用标记。

我已经使用了前面提到的ReportLab / Pisa设置,但发现它非常有限,大多数布局必须使用表格构建,CSS2规范的许多部分尚未实现。

更容易使用的库是wkhtmltopdf,它是WebKit的无头分发。这样可以像任何webkit浏览器一样呈现您的模板,从而让您使用webkit特定的附加功能,例如WebKit中存在的CSS3规范的部分内容。

使用包装库django-wkhtmltopdf,您可以在视图中render_to_pdf而不是通常的Django render_to_response

免责声明:我是该图书馆的撰稿人。

更新

此库已转换为CBV,下面的大部分信息(我将留下以帮助添加一些上下文)现在已在库本身中实现,以方便使用。

有关如何实现以下代码块的示例,请参阅quickstart文档。如果您需要使用更高级的用法,可以继承PDFTemplateView并添加各种选项,如文件名和边距。

示例视图:

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传递给视图,以便您可以在浏览器中进行开发。目前这是一种丑陋的方式,但有计划很快在发布中解决这个问题。

使用此视图,您可以像平常一样在视图中循环objects的内容,甚至可以扩展基本模板。我通常使用专门针对PDF的不同样式表来提供样式的可维护性和可读性,因为您需要为PDF做一些不同的事情,例如如果要将页脚块保持在同一位置,请设置最小高度

在本文中,您可以创建将在PDF的每个页面上使用的页眉和页脚模板,方法是将它们作为kwargs的一部分传递给render_to_pdf。

答案 1 :(得分:2)

只需按照您希望的方式生成HTML,然后让xhtml2pdf将其转换为pdf。

与其中一条评论一样,有ReportLab,但这需要您以PDF格式提供规范。它为您提供了更多控制,但如果您更容易生成HTML,无论如何都需要生成标准方法,您可以使用pisa将其设为pdf。

答案 2 :(得分:0)

使用wkhtmltopdf

尝试python-pdfkit

这似乎是最好的解决方案。支持javascript和css

答案 3 :(得分:0)

我为此创建了一个django应用程序:Django-pdf-generator

views.py中,只需执行:

from pdf_generator.renderers import render_pdf

def get_my_pdf(request):
    """
    returns a pdf file named my_awesome_pdf.pdf using awesome_pdf.html template
    """
    return render_pdf('my_awesome_pdf', request, 'awesome_pdf.html', context={})

请告诉我这是否对您有用。