如何建立 PDF 檔案¶
本文說明如何使用 Django 視圖動態輸出 PDF 檔案。這得益於優秀的開源 ReportLab Python PDF 函式庫。
動態產生 PDF 檔案的優勢在於您可以為不同的目的(例如,為不同的使用者或不同的內容)建立客製化的 PDF。
例如,kusports.com 使用 Django 來為參加三月瘋狂競賽的人們生成客製化的、適合列印的 NCAA 錦標賽對戰表,以 PDF 檔案的形式呈現。
安裝 ReportLab¶
ReportLab 函式庫可在 PyPI 上取得。一份 使用者指南(巧合的是,也是一個 PDF 檔案)也可供下載。您可以使用 pip
安裝 ReportLab
$ python -m pip install reportlab
...\> py -m pip install reportlab
在 Python 互動式直譯器中匯入它來測試您的安裝
>>> import reportlab
如果該指令沒有引發任何錯誤,則安裝成功。
撰寫您的視圖¶
使用 Django 動態產生 PDF 的關鍵在於 ReportLab API 會對檔案類物件進行操作,而 Django 的 FileResponse
物件接受檔案類物件。
以下是一個「Hello World」範例
import io
from django.http import FileResponse
from reportlab.pdfgen import canvas
def some_view(request):
# Create a file-like buffer to receive PDF data.
buffer = io.BytesIO()
# Create the PDF object, using the buffer 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, and we're done.
p.showPage()
p.save()
# FileResponse sets the Content-Disposition header so that browsers
# present the option to save the file.
buffer.seek(0)
return FileResponse(buffer, as_attachment=True, filename="hello.pdf")
程式碼和註解應該是不言自明的,但有幾件事值得一提
回應會根據檔案名稱副檔名自動設定 MIME 類型 application/pdf。這會告訴瀏覽器該文件是 PDF 檔案,而不是 HTML 檔案或通用的 application/octet-stream 二進位內容。
當將
as_attachment=True
傳遞給FileResponse
時,它會設定適當的Content-Disposition
標頭,這會告訴網頁瀏覽器彈出一個對話方塊,提示/確認如何處理該文件,即使機器上已設定預設值。如果省略as_attachment
參數,瀏覽器將使用它們已設定為用於 PDF 的任何程式/外掛程式來處理 PDF。您可以提供任意的
filename
參數。它將由瀏覽器在「另存為…」對話方塊中使用。您可以連接到 ReportLab API:作為
canvas.Canvas
的第一個參數傳遞的相同緩衝區可以饋送到FileResponse
類別。請注意,所有後續的 PDF 生成方法都是在 PDF 物件上(在本例中為
p
)呼叫,而不是在buffer
上。最後,務必在 PDF 檔案上呼叫
showPage()
和save()
。
注意
ReportLab 不是執行緒安全的。我們的一些使用者回報說,同時被多人存取的建構 PDF 生成 Django 視圖時會發生奇怪的問題。
其他格式¶
請注意,這些範例中沒有太多特定於 PDF 的內容,只有使用 reportlab
的部分。您可以使用類似的技術來產生您可以找到 Python 函式庫的任何任意格式。另請參閱 如何建立 CSV 輸出,其中包含另一個範例以及產生基於文字的格式時可以使用的一些技術。
另請參閱
Django Packages 提供 用於比較 協助從 Django 產生 PDF 檔案的套件。