如何创建PDF文件

本文档介绍如何使用django视图动态输出PDF文件。这是由优秀的、开源的 ReportLab python pdf库。

动态生成PDF文件的好处在于,您可以为不同的目的(例如,为不同的用户或不同的内容片段)创建定制的PDF。

例如,Django在 kusports.com 为参加三月疯狂竞赛的人生成定制的、打印机友好的NCAA锦标赛支架,如PDF文件。

安装ReportLab

ReportLab库是 available on PyPI 。一个 user guide (并非巧合的是,PDF文件)也可供下载。可以使用以下命令安装ReportLab pip

$ python -m pip install reportlab
...\> py -m pip install reportlab

通过将其导入到Python交互式解释器中来测试您的安装:

>>> import reportlab

如果该命令没有引发任何错误,则安装工作正常。

编写你的视图

使用django动态生成pdf的关键是ReportLab API对文件(如对象)和django的 FileResponse 对象接受类似对象的文件。

下面是一个“你好世界”的例子:

import io
from django.http import FileResponse
from reportlab.pdfgen import canvas


def some_view(request):
    # Create a file-like buffer to receive PDF data.
    buffer = io.BytesIO()

    # Create the PDF object, using the buffer as its "file."
    p = canvas.Canvas(buffer)

    # Draw things on the PDF. Here's where the PDF generation happens.
    # See the ReportLab documentation for the full list of functionality.
    p.drawString(100, 100, "Hello world.")

    # Close the PDF object cleanly, and we're done.
    p.showPage()
    p.save()

    # FileResponse sets the Content-Disposition header so that browsers
    # present the option to save the file.
    buffer.seek(0)
    return FileResponse(buffer, as_attachment=True, filename="hello.pdf")

代码和注释应该是不言自明的,但有几点值得一提:

  • 响应将自动设置mime类型 application/pdf 基于文件扩展名。这会告诉浏览器文档是PDF文件,而不是HTML文件或通用文件 application/octet-stream 二进制内容。

  • 什么时候 as_attachment=True 被传递到 FileResponse ,它设置适当的 Content-Disposition 标题,并告诉Web浏览器弹出一个对话框,提示/确认如何处理文档,即使机器上设置了默认设置。如果 as_attachment 参数被省略,浏览器将使用它们被配置为用于PDF的任何程序/插件来处理PDF。

  • 您可以提供任意 filename 参数。浏览器将在“另存为…”对话框中使用它。

  • 您可以挂接到reportlabapi:与传递给的第一个参数相同的缓冲区 canvas.Canvas 可以喂给 FileResponse 班级。

  • 请注意,所有随后的PDF生成方法都是在PDF对象上调用的(在本例中, p --不在 buffer .

  • 最后,调用很重要 showPage()save() 在PDF文件上。

备注

ReportLab不是线程安全的。我们的一些用户报告了构建生成django视图的PDF时出现的一些奇怪问题,这些视图可同时被许多人访问。

其它格式

注意,这些例子中没有很多特定于PDF的内容——只是使用 reportlab . 您可以使用类似的技术来生成任何可以为其找到Python库的任意格式。也看到 如何创建CSV输出 另一个例子和一些在生成基于文本的格式时可以使用的技术。

参见

Django软件包提供 comparison of packages 这有助于从Django生成PDF文件。