便攜文檔格式 (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 canvasfrom django.http import HttpResponsedef 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 StringIOfrom reportlab.pdfgen import canvasfrom django.http import HttpResponsedef 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”內容的內建工具。