利用Python的Django框架生成PDF文件的教程


Posted in Python onJuly 22, 2015

便携文档格式 (PDF) 是由 Adobe 开发的格式,主要用于呈现可打印的文档,其中包含有 pixel-perfect 格式,嵌入字体以及2D矢量图像。 You can think of a PDF document as the digital equivalent of a printed document; indeed, PDFs are often used in distributing documents for the purpose of printing them.

可以方便的使用 Python 和 Django 生成 PDF 文档需要归功于一个出色的开源库, ReportLab (http://www.reportlab.org/rl_toolkit.html) 。动态生成 PDF 文件的好处是在不同的情况下,如不同的用户或者不同的内容,可以按需生成不同的 PDF 文件。 The advantage of generating PDF files dynamically is that you can create customized PDFs for different purposes say, for different users or different pieces of content.

下面的例子是使用 Django 和 ReportLab 在 KUSports.com 上生成个性化的可打印的 NCAA 赛程表 (tournament brackets) 。
安装 ReportLab

在生成 PDF 文件之前,需要安装 ReportLab 库。这通常是个很简单的过程: Its usually simple: just download and install the library from http://www.reportlab.org/downloads.html.

Note

如果使用的是一些新的 Linux 发行版,则在安装前可以先检查包管理软件。 多数软件包仓库中都加入了 ReportLab 。

比如,如果使用(杰出的) Ubuntu 发行版,只需要简单的 apt-get install python-reportlab 一行命令即可完成安装。

使用手册(原始的只有 PDF 格式)可以从 http://www.reportlab.org/rsrc/userguide.pdf 下载,其中包含有一些其它的安装指南。

在 Python 交互环境中导入这个软件包以检查安装是否成功。

>>> import reportlab

如果刚才那条命令没有出现任何错误,则表明安装成功。
编写视图

和 CSV 类似,由 Django 动态生成 PDF 文件很简单,因为 ReportLab API 同样可以使用类似文件对象。

下面是一个 Hello World 的示例:

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

def hello_pdf(request):
  # Create the HttpResponse object with the appropriate PDF headers.
  response = HttpResponse(mimetype='application/pdf')
  response['Content-Disposition'] = 'attachment; filename=hello.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 文档,这会使浏览器的窗口中出现很奇怪的文字。 If you leave off this information, browsers will probably interpret the response as HTML, which will result in scary gobbledygook in the browser window.

    使用 ReportLab 的 API 很简单: 只需要将 response 对象作为 canvas.Canvas 的第一个参数传入。

    所有后续的 PDF 生成方法需要由 PDF 对象调用(在本例中是 p ),而不是 response 对象。

    最后需要对 PDF 文件调用 showPage() 和 save() 方法(否则你会得到一个损坏的 PDF 文件)。

复杂的 PDF 文件

如果您在创建一个复杂的 PDF 文档(或者任何较大的数据块),请使用 cStringIO 库存放临时生成的 PDF 文件。 cStringIO 提供了一个用 C 编写的类似文件对象的接口,从而可以使系统的效率最高。

下面是使用 cStringIO 重写的 Hello World 例子:

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

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

  temp = StringIO()

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

  # 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 StringIO buffer and write it to the response.
  response.write(temp.getvalue())
  return response

其它的可能性

使用 Python 可以生成许多其它类型的内容,下面介绍的是一些其它的想法和一些可以用以实现它们的库。 Here are a few more ideas and some pointers to libraries you could use to implement them:

    ZIP 文件 :Python 标准库中包含有 zipfile 模块,它可以读和写压缩的 ZIP 文件。 它可以用于按需生成一些文件的压缩包,或者在需要时压缩大的文档。 如果是 TAR 文件则可以使用标准库 tarfile 模块。

    动态图片 : Python 图片处理库 (PIL; http://www.pythonware.com/products/pil/) 是极好的生成图片(PNG, JPEG, GIF 以及其它许多格式)的工具。 它可以用于自动为图片生成缩略图,将多张图片压缩到单独的框架中,或者是做基于 Web 的图片处理。

    图表 : Python 有许多出色并且强大的图表库用以绘制图表,按需地图,表格等。 我们不可能将它们全部列出,所以下面列出的是个中的翘楚。

        matplotlib (http://matplotlib.sourceforge.net/) 可以用于生成通常是由 matlab 或者 Mathematica 生成的高质量图表。

        pygraphviz (https://networkx.lanl.gov/wiki/pygraphviz) 是一个 Graphviz 图形布局的工具 (http://graphviz.org/) 的 Python 接口,可以用于生成结构化的图表和网络。

总之,所有可以写文件的库都可以与 Django 同时使用。 The possibilities are immense.

我们已经了解了生成“非HTML”内容的基本知识,让我们进一步总结一下。 Django拥有很多用以生成各类“非HTML”内容的内置工具。

Python 相关文章推荐
用Python程序抓取网页的HTML信息的一个小实例
May 02 Python
python通过post提交数据的方法
May 06 Python
Python 关于反射和类的特殊成员方法
Sep 14 Python
有趣的python小程序分享
Dec 05 Python
Python决策树分类算法学习
Dec 22 Python
Python爬虫实现全国失信被执行人名单查询功能示例
May 03 Python
Python 统计字数的思路详解
May 08 Python
在Django中URL正则表达式匹配的方法
Dec 20 Python
对python xlrd读取datetime类型数据的方法详解
Dec 26 Python
python爬取基于m3u8协议的ts文件并合并
Apr 26 Python
Django框架设置cookies与获取cookies操作详解
May 27 Python
Jupyter加载文件的实现方法
Apr 14 Python
在Python的Django框架中生成CSV文件的方法
Jul 22 #Python
在主机商的共享服务器上部署Django站点的方法
Jul 22 #Python
在Lighttpd服务器中运行Django应用的方法
Jul 22 #Python
简单的Apache+FastCGI+Django配置指南
Jul 22 #Python
使用FastCGI部署Python的Django应用的教程
Jul 22 #Python
使用相同的Apache实例来运行Django和Media文件
Jul 22 #Python
在Apache服务器上同时运行多个Django程序的方法
Jul 22 #Python
You might like
暴雪前总裁遗憾:没尽早追赶Dota 取消星际争霸幽灵
2020/03/08 星际争霸
php+mysql开源XNA 聚合程序发布 下载
2007/07/13 PHP
php使HTML标签自动补全闭合函数代码
2012/10/04 PHP
php实现通过ftp上传文件
2015/06/19 PHP
非常经典的PHP文件上传类分享
2016/05/15 PHP
锋利的jQuery 要点归纳(三) jQuery中的事件和动画(下:动画篇)
2010/03/24 Javascript
将两个div左右并列显示并实现点击标题切换内容
2013/10/22 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
2015/12/03 Javascript
基于jquery实现简单的分页控件
2016/03/17 Javascript
JavaScript实现点击文本自动定位到下拉框选中操作
2016/06/15 Javascript
前端框架Vue.js中Directive知识详解
2016/09/12 Javascript
Angular.js中$apply()和$digest()的深入理解
2016/10/13 Javascript
Angularjs 依赖压缩及自定义过滤器写法
2017/02/04 Javascript
angularJS 发起$http.post和$http.get请求的实现方法
2017/05/18 Javascript
原生JS实现的多个彩色小球跟随鼠标移动动画效果示例
2018/02/01 Javascript
详解vue中点击空白处隐藏div的实现(用指令实现)
2018/04/19 Javascript
vue实现点击当前标签高亮效果【推荐】
2018/06/22 Javascript
javascript设计模式 ? 职责链模式原理与用法实例分析
2020/04/16 Javascript
[07:54]DOTA2 MV《我的动力鞋》 ImbaTV 出品
2014/11/21 DOTA
Python基于QRCode实现生成二维码的方法【下载,安装,调用等】
2017/07/11 Python
python中使用zip函数出现错误的原因
2018/09/28 Python
python中的单引号双引号区别知识点总结
2019/06/23 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
2019/06/28 Python
python requests库爬取豆瓣电视剧数据并保存到本地详解
2019/08/10 Python
Python学习笔记之While循环用法分析
2019/08/14 Python
tensorflow estimator 使用hook实现finetune方式
2020/01/21 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
一款纯css3实现简单的checkbox复选框和radio单选框
2014/11/05 HTML / CSS
银行会计业务的个人自我评价
2013/11/02 职场文书
自动化专业个人求职信范文
2013/12/30 职场文书
个人职业生涯规划书1500字
2013/12/31 职场文书
大学生开西餐厅创业计划书
2014/02/01 职场文书
社区党建工作汇报材料
2014/08/14 职场文书
教学工作总结范文5篇
2019/08/19 职场文书
pycharm无法导入lxml的解决办法
2021/03/31 Python
Redis基本数据类型Set常用操作命令
2022/06/01 Redis