1. 程式人生 > >Django 2.1.3 文件-檢視層-生成PDF

Django 2.1.3 文件-檢視層-生成PDF

用Django輸出PDF

本文件介紹瞭如何使用Django檢視動態輸出PDF檔案。這是通過優秀的開源Python PDF庫ReportLab 實現的。

動態生成PDF檔案的優點是,您可以為不同目的建立自定義PDF,例如,針對不同使用者或不同內容。

例如,Django在kusports.com上使用,為參與March Madness比賽的人們生成定製的,適合列印的NCAA錦標賽PDF檔案。

安裝ReportLab

ReportPab庫可在PyPI上使用。一個使用者指南(PDF檔案)也可供下載。您可以使用以下 pip命令安裝ReportLab:

 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. return FileResponse(buffer, as_attachment=True, filename='hello.pdf')

程式碼和註釋應該是不言自明的,但有些事情值得一提:

  • 響應將 根據副檔名自動設定MIME型別為 application / pdf。這告訴瀏覽器該文件是PDF檔案,而不是HTML檔案或application/octet-stream的二進位制內容。
  • 傳遞給FileResponse一個as_attachment=True屬性時,它設定適當的Content-Disposition標題,並告訴Web瀏覽器彈出一個對話方塊,提示/確認如何處理文件,即使在機器上設定了預設值。如果as_attachment省略該引數,瀏覽器將使用它們已配置用於PDF的任何程式/外掛來處理PDF。
  • 您可以提供任意filename引數。瀏覽器將在“另存為…”對話方塊中使用它。
  • 連線到ReportLab API非常簡單:傳遞給canvas.Canvas的第一個衝區引數緩也可以提供給 FileResponse類。
  • 請注意,所有後續PDF生成方法都在PDF物件上呼叫(在本例中p),而不是buffer。
  • 最後,呼叫PDF檔案上的showPage()和save()非常重要。

註解
ReportLab不是執行緒安全的。我們的一些使用者報告了構建生成PDF的Django檢視的奇怪問題,這些檢視可以被許多人同時訪問。

譯者注:
上面的程式碼是Django 2.1提供的,本地測試暫時不能生成文件:
下面附上可以生成PDF文件的程式碼(Django 2.0提供):

def generate_pdf(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

其他格式

請注意,這些示例中沒有很多特定於PDF的內容 - 只是使用了reportlab的一點。您可以使用類似的技術生成任何可以找到Python庫的任意格式。另請參閱 使用Django輸出CSV以獲取另一個示例以及在生成基於文字的格式時可以使用的一些技巧。

參見

Django Packages提供了有助於從Django生成PDF檔案的一些軟體包