如何创建 PDF 文件

本文档解释了如何使用 Django 视图动态输出 PDF 文件。这得益于优秀的开源 ReportLab Python PDF 库。

动态生成 PDF 文件的优势在于,您可以为不同的目的创建自定义的 PDF 文件——例如,为不同的用户或不同的内容。

例如,kusports.com 使用 Django 生成自定义的、适合打印的 NCAA 锦标赛积分榜(PDF 文件),供参与疯狂三月比赛的人使用。

安装 ReportLab

ReportLab 库可在 PyPI 上获得。还可以下载 用户指南(巧合的是,它也是一个 PDF 文件)。您可以使用 pip 安装 ReportLab

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

通过在 Python 交互式解释器中导入它来测试您的安装

>>> import reportlab

如果该命令没有引发任何错误,则安装成功。

编写您的视图

使用 Django 动态生成 PDF 文件的关键在于,ReportLab API 对类文件对象进行操作,而 Django 的 FileResponse 对象接受类文件对象。

这是一个“Hello World”示例

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 参数。浏览器将在“另存为…”对话框中使用它。

  • 您可以连接到 ReportLab API:作为第一个参数传递给 canvas.Canvas 的相同缓冲区可以馈送到 FileResponse 类。

  • 请注意,所有后续的 PDF 生成方法都调用 PDF 对象(在本例中为 p),而不是 buffer

  • 最后,务必在 PDF 文件上调用 showPage()save()

注意

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

其他格式

请注意,在这些示例中,没有太多特定于 PDF 的内容——只有使用 reportlab 的部分。您可以使用类似的技术来生成您可以找到 Python 库的任何任意格式。另请参阅 如何创建 CSV 输出,了解另一个示例以及生成文本格式时可以使用的一些技术。

另见

Django Packages 提供了 帮助从 Django 生成 PDF 文件的软件包的比较

返回顶部