django 1.8 官方文档翻译: 3-5-2 使用Django输出PDF

简介: 使用Django输出PDF这篇文档阐述了如何通过使用Django视图动态输出PDF。这可以通过一个出色的、开源的Python PDF库ReportLab来实现。

使用Django输出PDF

这篇文档阐述了如何通过使用Django视图动态输出PDF。这可以通过一个出色的、开源的Python PDF库ReportLab来实现。

动态生成PDF文件的优点是,你可以为不同目的创建自定义的PDF – 这就是说,为不同的用户或者不同的内容。

例如,Django在kusports.com上用来为那些参加March Madness比赛的人,生成自定义的,便于打印的 NCAA 锦标赛晋级表作为PDF文件。

安装ReportLab

ReportLab库在PyPI上提供。也可以下载到用户指南 (PDF文件,不是巧合)。 你可以使用pip来安装ReportLab:

$ pip install reportlab

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

>>> import reportlab

若没有抛出任何错误,则已安装成功。

编写你的视图

使用Django动态生成PDF的关键是,ReportLab API作用于类似于文件的对象,并且Django的 HttpResponse对象就是类似于文件的对象。

这里是一个 “Hello World”的例子:

from reportlab.pdfgen import canvas
from django.http import HttpResponse

def some_view(request):
    # Create the HttpResponse object with the appropriate PDF headers.
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'

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

    # 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()
    return response

代码和注释是不用多说的,但是一些事情需要提醒一下:

  • 响应对象获得了一个特殊的MIME类型, application/pdf。这会告诉浏览器,文档是个PDF文件而不是HTML文件。 如果你把它去掉,浏览器可能会把输出解释为HTML,会在浏览器窗口中显示一篇丑陋的、可怕的官样文章。
  • 响应对象获取了附加的Content-Disposition协议头,它含有PDF文件的名称。 文件名可以是任意的;你想把它叫做什么都可以。浏览器会在”另存为“对话框中使用它,或者其它。
  • 在这个例子中,Content-Disposition 协议头以 'attachment;' 开头。 这样就强制让浏览器弹出对话框来提示或者确认,如果机器上设置了默认值要如何处理文档。如果你去掉了'attachment;',无论什么程序或控件被设置为用于处理PDF,浏览器都会使用它。代码就像这样:
response['Content-Disposition'] = 'filename="somefilename.pdf"'
  • 钩住ReportLab API 非常简单:只需要向canvas.Canvas传递response作为第一个参数。Canvas函数接受一个类似于文件的对象,而 HttpResponse对象正好合适。
  • 注意所有随后的PDF生成方法都在PDF对象(这个例子是p)上调用,而不是response对象上。
  • 最后,在PDF文件上调用showPage()save()非常重要。

注意

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

复杂的PDF

如果你使用ReportLab创建复杂的PDF文档,考虑使用io库作为你PDF文件的临时保存地点。这个库提供了一个类似于文件的对象接口,非常实用。这个是上面的“Hello World”示例采用 io重写后的样子:

from io import BytesIO
from reportlab.pdfgen import canvas
from django.http import HttpResponse

def some_view(request):
    # Create the HttpResponse object with the appropriate PDF headers.
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'

    buffer = BytesIO()

    # Create the PDF object, using the BytesIO object 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.
    p.showPage()
    p.save()

    # Get the value of the BytesIO buffer and write it to the response.
    pdf = buffer.getvalue()
    buffer.close()
    response.write(pdf)
    return response

更多资源

  • PDFlib与Python捆绑的另一个PDF生成库。在Django中使用它的方法和这篇文章所阐述的相同。
  • Pisa XHTML2PDF是另一个PDF生成库。Pisa自带了如何将 Pisa 集成到 Django的例子。
  • HTMLdoc是一个命令行脚本,它可以把HTML转换为PDF。它并没有Python接口,但是你可以使用system 或者 popen,在控制台中使用它,然后再Python中取回输出。

其它格式

要注意在这些例子中并没有很多PDF特定的东西 – 只是使用了reportlab。你可以使用相似的技巧来生成任何格式,只要你可以找到对应的Python库。关于用于生成基于文本的格式的其它例子和技巧,另见使用Django输出CSV

译者:Django 文档协作翻译小组,原文:Generating PDF

本文以 CC BY-NC-SA 3.0 协议发布,转载请保留作者署名和文章出处。

Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。交流群:467338606。

相关文章
|
5月前
|
前端开发 开发工具 git
Django实践-06导出excel/pdf/echarts
Django实践-06导出excel/pdf/echarts
Django实践-06导出excel/pdf/echarts
|
5月前
|
Ubuntu 前端开发 Linux
django(六)使用wkhtmltopdf将网页导出PDF
如题,我需要使用python 将 网页 转成PDF文件,这里会用到wkhtmltopdf 我这里使用的是centos服务器。(使用ubuntu事会少很多,别问我为什么不用,我的web项目使用的是PHP,相对来说,centos部署web项目要比ubuntu要好) Python需要用到扩展 pdfkit
78 0
|
JSON 前端开发 JavaScript
Django结合Vue实现前端页面导出为PDF2
Django结合Vue实现前端页面导出为PDF
191 0
|
前端开发 JavaScript 测试技术
Django结合Vue实现前端页面导出为PDF1
Django结合Vue实现前端页面导出为PDF
103 0
|
API Python 调度
django 1.8 官方文档翻译: 3-4-1 基于类的视图
基于类的视图 视图是一个可调用对象,它接收一个请求然后返回一个响应。这个可调用对象可以不只是函数,Django 提供一些可以用作视图的类。
752 0
|
Web App开发 缓存 安全
django 1.8 官方文档翻译: 3-6-2 内建的中间件
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html 中间件 这篇文档介绍了Django自带的所有中间件组件。
1214 0
|
Python
django 1.8 官方文档翻译: 4-2-4 人性化
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html django.contrib.humanize 一系列Django的模板过滤器,有助于向数据添加“人文关怀”。
779 0
|
数据库 Python 开发者
django 1.8 官方文档翻译: 3-4-2 内建显示视图
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html 基于类的内建通用视图 编写Web应用可能是单调的,因为你需要不断的重复某一种模式。
740 0
|
中间件 Python
django 1.8 官方文档翻译: 3-6-1 中间件概览
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html 中间件 中间件是一个介入Django的请求和响应的处理过程中的钩子框架。
1029 0
|
SQL 测试技术 数据库
django 1.8 官方文档翻译: 2-6-3 提供初始数据
Django 文档协作翻译小组人手紧缺,有兴趣的朋友可以加入我们,完全公益性质。 交流群:467338606 网站:http://python.usyiyi.cn/django/index.html 为模型提供初始数据 当你首次建立一个应用的时候,为你的数据库预先安装一些硬编码的数据,是很有用处的。
996 0