最近在公司一直忙着做exe安裝包,以及為程序添加新功能,好久沒有繼續來寫關於Django的東西了….難得這個周末清閑,來了解了解Django的一些小功能也是極好的了~
那今天就來看看在Django的視圖中將頁面導出為pdf格式的功能吧。那么動態生成pdf的好處是什么呢?你可以為不同目的的用戶創建定制的pdf。那么是如何實現的呢?它使用的是Python開源的pdf庫---ReportLab
安裝ReportLab
你可以從http://www.reportlab.com/software/opensource/rl-toolkit/download/下載安裝ReportLab庫,有個用戶指南來解釋如何安裝它,或者你也可以使用pip來安裝。
sudo pip install reportlab
測試你是否成功安裝好了ReportLab
>>> import reportlab
如果這個命令沒有報任何錯誤的話就說明ReportLab已經成功安裝好了。
Django動態生成pdf的關鍵是ReportLab關於文件的API接口,APi接口是文件對象,而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
這里response得到一個特殊的MIME類型 'application/pdf’這個標示告訴瀏覽器這是一個PDF文件,而非一個HTML文件,如果你不這樣的話瀏覽器會解釋輸出為HTML的文件格式,這樣會導致在窗口展示十分的丑陋。
同時,response會得到一個額外的內容,這其中包括了PDF文件的名稱,當然這個文件名是任意的,你可以使用瀏覽器的另存為來給它取任何的名字。這這個例子中緊接着會彈出對話框來確認如何處理文檔。最后最重要的是使用showPage()方法和save()方法來保存導出的PDf文件了。
注意:ReportLab是非線程安全的。
那現在我們來看看復雜的PDF文件,如果你要用ReportLab創建一個復雜的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
當然,除了ReportLab庫之外還有很多優秀的Python第三方庫,例如:
PDFlib:是Django綁定了另外一個Python庫,還有諸如“XHTML2PDF”庫,還有就是使用“HTMLdoc”,它是一個將HTML轉成PDF的命令行,但是它沒有接口,只能使用Python的輸入輸出界面。