Django能够使用视图动态地输出PDF文件。 这是由优秀的开源ReportLab Python PDF库实现的。 动态生成PDF文件的优点是您可以为不同的目的创建自定义的PDF - 例如,针对不同的用户或不同的内容片段。
安装Reportlab
ReportLab库在PyPI上可用。 用户指南(并非巧合的是PDF文件)也可以下载。 您可以使用pip安装ReportLab:
$ pip install reportlab
通过将它导入Python交互式解释器来测试您的安装:
>>> import reportlab
如果该命令不会引发任何错误,则安装成功了,可以正常工作。
写入你的视图
使用Django动态生成PDF的关键是ReportLab API,就像csv库一样,可以处理文件类对象,如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文件。
-
该响应获得一个额外的Content-Disposition标题,其中包含PDF文件的名称。 这个文件名是任意的:你可以随意调用它。 它将被另存为...对话框中的浏览器使用
-
Content-Disposition头以'attachment; '在这个例子中。 这会强制Web浏览器弹出一个对话框,提示/确认如何处理文档,即使在机器上设置了默认值。 如果你离开“附件”,浏览器将使用他们已经配置用于PDF的任何程序/插件来处理PDF。 该代码看起来像这样:
response['Content-Disposition'] = 'filename="somefilename.pdf"'
-
连接ReportLab API非常简单:只需将response作为第一个参数传递给canvas.Canvas即可。 Canvas类需要一个类似文件的对象,并且HttpResponse对象符合账单。
-
请注意,所有后续的PDF生成方法都是在PDF对象上调用的(在本例中为p) - 而不是响应。
-
最后,在PDF文件上调用showPage()和save()很重要。
复杂的PDF文件
如果您使用ReportLab创建复杂的PDF文档,请考虑将io库用作PDF文件的临时保存位置。 这个库提供了一个特别高效的文件类对象接口。 以上是重写为使用io的Hello World示例:
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接口,但可以使用系统或popen转义到shell,并使用Python检索输出。
其他可能性
有很多其他类型的内容可以用Python生成。 这里有一些更多的想法和一些指向你可以用来实现它们的库的指针:
- ZIP文件:Python的标准库附带zipfile模块,它可以读取和写入压缩的ZIP文件。 您可以使用它来提供一堆文件的按需存档,或者在请求时压缩大型文档。 您可以使用标准库的tarfile模块类似地生成TAR文件。
- 动态图像:Python图像库(PIL)是生成图像(PNG,JPEG,GIF等等)的绝佳工具包。 您可以使用它自动将图像缩小为缩略图,
将多个图像合成为一个帧,甚至可以执行基于Web的图像处理。 - 绘图和图表:您可以使用许多功能强大的Python绘图和绘图库生成按需地图,图表,图表和图表。 我们不可能将它们全部列出,所以这里有几个亮点:
- matplotlib可用于生成通常由MatLab或Mathematica生成的高质量图的类型。
- pygraphviz是Graphviz图形布局工具包的一个接口,可用于生成图形和网络的结构图。
一般来说,任何能够写入文件的Python库都可以挂钩到Django中。 可能性是巨大的。 现在我们已经介绍了生成非HTML内容的基础知识,让我们加强抽象层次。 Django附带一些非常漂亮的内置工具,用于生成一些常见类型的非HTML内容。
网友评论