使用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 HttpResponsedef 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 HttpResponsedef 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。

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

  1. django 1.8 官方文档翻译: 2-5-7 自定义查找

    自定义查找 New in Django 1.7. Django为过滤提供了大量的内建的查找(例如,exact和icontains).这篇文档阐述了如何编写自定义查找,以及如何修改现存查找的功能.关于查 ...

  2. django 1.8 官方文档翻译: 2-5-6 多数据库

    多数据库 这篇主题描述Django 对多个数据库的支持.大部分Django 文档假设你只和一个数据库打交道.如果你想与多个数据库打交道,你将需要一些额外的步骤. 定义你的数据库 在Django中使用多 ...

  3. django 1.8 官方文档翻译:13-1-3 密码管理

    Django中的密码管理 密码管理在非必要情况下一般不会重新发明,Django致力于提供一套安全.灵活的工具集来管理用户密码.本文档描述Django存储密码和hash存储方法配置的方式,以及使用has ...

  4. django 1.8 官方文档翻译:13-3 日志

    日志 日志快速入门 Django 使用Python 内建的logging 模块打印日志.该模块的用法在Python 本身的文档中有详细的讨论.如果你从来没有使用过Python 的logging 框架( ...

  5. django 1.8 官方文档翻译: 8-3 点击劫持保护

    点击劫持保护 点击劫持中间件和装饰器提供了简捷易用的,对点击劫持的保护.这种攻击在恶意站点诱导用户点击另一个站点的被覆盖元素时出现,另一个站点已经加载到了隐藏的frame或iframe中. 点击劫持的 ...

  6. django 1.8 官方文档翻译: 2-5-10 数据库函数

    数据库函数 New in Django 1.8. 下面记述的类为用户提供了一些方法,来在Django中使用底层数据库提供的函数用于注解.聚合或者过滤器等操作.函数也是表达式,所以可以像聚合函数一样混合 ...

  7. django 1.8 官方文档翻译: 3-3-5 编写自定义存储系统

    编写自定义存储系统 如果你需要提供自定义文件存储 – 一个普遍的例子是在某个远程系统上储存文件 – 你可以通过定义一个自定义的储存类来实现.你需要遵循以下步骤: 1. 你的自定义储存类必须是djang ...

  8. django 1.8 官方文档翻译: 3-5-1 使用Django输出CSV

    使用Django输出CSV 这篇文档阐述了如何通过使用Django视图动态输出CSV (Comma Separated Values). 你可以使用Python CSV 库或者Django的模板系统来 ...

  9. django 1.8 官方文档翻译: 2-3-1 模型实例参考

    模型实例参考 该文档详细描述模型 的API.它建立在模型 和执行查询 的资料之上, 所以在阅读这篇文档之前,你可能会想要先阅读并理解那两篇文档. 我们将用执行查询中所展现的 博客应用模型 来贯穿这篇参 ...

最新文章

  1. Android依赖注入的实践——Dagger2
  2. Java设计模式(五):单例设计模式
  3. arcgis公里坐标转经纬度_高德api交通态势爬取及可视化利用 python+arcgis
  4. JZOJ 100035. 【NOIP2017提高A组模拟7.10】区间
  5. 文本分类入门(九)文本分类问题的分类
  6. pd 生成mysql 脚本_PowerDesigner 如何生成数据库更新脚本
  7. esp32搭建文件服务器,ESP32入门示例 - SD卡Web服务器
  8. 360浏览器鼠标手势怎么关 取消360浏览器鼠标手势的方法
  9. Bioconda软件安装神器:多版本并存、环境复制、环境导出
  10. bzoj3744: Gty的妹子序列 (BIT 分块)
  11. [数据]matplotlib总结
  12. c++冒泡排序的类模板的实现
  13. mysql 参考文献_后记amp;参考文献
  14. python多个文件打包成exe_多个py文件生成一个可运行exe文件
  15. C语言简单直观打印二叉树
  16. Linux设备模型分析之kobject
  17. 基于java spring框架开发部标1078视频监控平台精华文章索引
  18. 北京定点医疗机构查询
  19. 局域网和广域网的WOL设置心得,共享给大家-组装NAS及黑群晖-奇珀网
  20. 聊聊华为,不得不说华为确实很牛逼

热门文章

  1. Vivado FIFO IP核接口信号介绍
  2. uk码对照表_这份中外衣服鞋码尺寸对照表,请收好!
  3. rfid技术及应用答案王佳斌_详解工业数据采集中RFID技术的应用
  4. STM32F103:一.(4)JWAG功能IO复用
  5. lwip 数据处理流程
  6. 1000以内所有同构数java算法_使用c语言求1到1000同构数的代码
  7. 带你一文看懂MySqL中的事务与索引
  8. python模拟给qq发消息,python模拟QQ聊天--socket通信
  9. word中添加mathtype
  10. 【重难点】【事务 03】分布式事务