现在的位置: 首页 > 综合 > 正文

利用Django生成PDF文档

2013年12月05日 ⁄ 综合 ⁄ 共 2886字 ⁄ 字号 评论关闭

利用Django生成PDF文档

本小节说明如何利用Django视图动态生成PDF文档。此功能是由优秀的开源Python PDF库ReportLab实现的。

动态生成PDF文档的好处在于你可以定制PDF文档以实现不同的目标,比如针对不同的用户或者不同的内容进行相关定制。

举例来说,在kusports.com网站上Django被用来生成美国大学生体育联盟(NCAA)锦标赛对阵表,这些自定义的适于打印的PDF文档可以服务于参与三月份冠军赛季的人们。

安装ReprotLab

http://www.reportlab.org/oss/rl-toolkit/download/可以下载并安装ReportLab库,附带的用户指南说明了安装方法。

可以使用如下指令将ReprotLab库导入Python交互解释器以测试安装情况:

>>> import reportlab

 

如果此命令没有输出任何错误则表明安装成功。

自定义视图

使用Django动态生成PDF文档的关键在于明白ReprotLabAPI作用于类文件对象,例如Django的HttpResponse对象就是类文件对象。

下面是一个“Hello World”的例子程序:

from reportlab.pdfgen import canvas
from django.http import HttpResponse
 
defsome_view(request):
# Create the HttpResponse object with the appropriate PDF headers.
response=HttpResponse(mimetype='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

 

以上代码和注释基本可以自解释,只有以下几点需要说明一下:

·  类文件对象response被指定了一个特殊的MIME类型——“application/pdf”。浏览器据此便知道这是一个PDF文档,而不是一个HTML文件。如果没有这个信息,浏览器很可能会以HTML形式输出文件,造成页面显示十分难看。

·  response还有一个附加的Content-Disposition首部,其中包含了PDF文件的名称。此文件名是任意的,你可以随意指定。浏览器将在“另存为”对话框等地方用到它。

·  Content-Disposition首部在本例中以“attachment;”起始。这一语句强制浏览器显示一个对话框来提示并请求确认如何处理当前文档,无论是否有其他的默认配置。如果你像下面所示的代码那样不写这个起始语句,则浏览器会使用默认程序或插件来处理PDF文档:

response['Content-Disposition']='filename=somefilename.pdf'

·  调用ReportLab API很简单,只需要将response作为第一个参数传递给canvas.Canvas。Canvas类需要一个类文件对象,而response作为HttpResponse对象正符合这个要求。

·  注意,所有后续的生成PDF的方法都以PDF对象(在本例中即为p)而不是response对象调用。

·  最后,对PDF文件对象调用函数showPage()和save()是很重要的。

复杂PDF文档的生成

如果你想使用ReprotLab库生成一个形式很复杂的PDF文档,可以考虑使用cStringIO库建立你的PDF文档的临时缓冲区以便进行更复杂的操作。cStringIO库提供了一个非常高效的类文件对象接口。以下是上面提到的“Hello World”例子的cStringIO版:

from cStringIO import StringIO
from reportlab.pdfgen import canvas
from django.http import HttpResponse
 
defsome_view(request):
# Create the HttpResponse object with the appropriate PDF headers.
response=HttpResponse(mimetype='application/pdf')
response['Content-Disposition']='attachment; filename=somefilename.pdf'
 
buffer=StringIO()
 
# Create the PDF object, using the StringIO 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 StringIO buffer and write it to the response.
pdf=buffer.getvalue()
buffer.close()
response.write(pdf)
return response

更多资源

  • PDFlib是另一个可用于生成PDF的库,提供了Python实现。利用本文中阐述的基本原理即可将它与Django集成起来使用。
  • Pisa XHTML2PDF也是一个用于生成PDF的库,同时自带一个如何在Django中集成使用Pisa的例子程序。
  • HTMLdoc是一个可以将HTML转换为PDF的命令行脚本,但并未提供Python接口。不过你可以使用system函数或者popen函数来执行这个命令行脚本,然后使用Python捕获输出进行处理。

其他格式

以上例子中除了使用reprotlab库的代码外,并没有多少只适用于PDF的处理。因此只要你找得到相应的Python库,可以使用类似的方法生成任意其他格式的文件。在使用Django生成CSV文件小节中有另一个例子,里面讲解了如何生成文本格式的文件。

抱歉!评论已关闭.