如何建立 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 檔案的套件。

返回頂端