如何创建 PDF 文件

如何创建 PDF 文件

本文说明如何利用 Django 视图动态输出 PDF 文件。这得益于出色的开源 Python PDF 库 ReportLab。

动态生成 PDF 的优势在于,可以针对不同用途创建定制的 PDF,例如为不同用户或不同内容生成不同文件。

例如,kusports.com 曾使用 Django,为参加 March Madness 竞猜的用户生成定制的 NCAA 锦标赛对阵表。这些对阵表采用 PDF 格式,便于打印。

安装 ReportLab

ReportLab 库可以从 PyPI 获取,也有可下载的用户指南,其格式恰好也是 PDF。可以使用 pip 安装:

$ python -m pip install reportlab

Windows:

...\> 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 响应头。即使机器上已有默认处理方式,这也会让浏览器弹出对话框,提示或确认如何处理文档。如果省略 as_attachment 参数,浏览器会使用已配置的 PDF 程序或插件处理文件。
  • 可以提供任意 filename 参数,浏览器会在“另存为”对话框中使用它。
  • 可以接入 ReportLab API:作为第一个参数传给 canvas.Canvas 的同一个缓冲区,也可以传给 FileResponse 类。
  • 后续生成 PDF 的方法都在 PDF 对象上调用,此处是 p,而不是 buffer。
  • 最后,必须在 PDF 文件对象上调用 showPage() 和 save()。

其他格式

这些示例中与 PDF 特有功能有关的部分其实不多,主要就是使用 reportlab 的代码。只要某种格式有对应的 Python 库,就可以采用类似方法生成该格式的文件。另请参阅输出 CSV,其中提供了另一种示例,以及生成文本格式时可使用的一些技巧。

另请参阅:Django Packages 提供了一份软件包对比,列出了帮助 Django 生成 PDF 的软件包。

来源与许可

来源:Django 文档:如何创建 PDF 文件;本文中文措辞依据官方英文文档源码重新翻译,示例代码与注释保持原样。Django 项目采用 BSD 3-Clause 许可,完整许可如下:

Copyright (c) Django Software Foundation and individual contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    1. Redistributions of source code must retain the above copyright notice,
       this list of conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.

    3. Neither the name of Django nor the names of its contributors may be used
       to endorse or promote products derived from this software without
       specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容