1. 程式人生 > 程式設計 >Django生成PDF文件顯示網頁上以及PDF中文顯示亂碼的解決方法

Django生成PDF文件顯示網頁上以及PDF中文顯示亂碼的解決方法

專案地址:https://github.com/PythonerKK/django-generate-pdf/tree/master

這個demo實現了通過使用者輸入自己的個人資訊生成一份簡歷pdf,來闡述如何使用Django的HttpResponse生成PDF的文件。

先上效果圖:

安裝依賴庫

首先安裝Django最新版2.2.2和PDF依賴包xhtml2pdf

pip install django
pip install xhtml2pdf

編寫表單驗證

為了簡單起見,這個demo依賴資料庫,只需要表單驗證資料即可

pdf/forms.py

class MessageForm(forms.Form):
  '''
  表單驗證
  '''
  name = forms.CharField(required=True)
  degree = forms.CharField(required=True)
  edu = forms.CharField(required=True)
  work = forms.CharField(required=True)
  tech = forms.CharField(required=True)
  phone = forms.CharField(required=True)

編寫類檢視

pdf/views.py

由於這裡我們只需要表單檢視,所以只建立了一個類檢視,post用來驗證表單資料是否都存在,如果存在就把表單資料渲染到PDF模板中,經過處理後返回PDF的響應response。

這裡可以使用Django的通用類檢視FormView構建,程式碼更簡潔

class MessageView(View):
  def get(self,request):
    form = MessageForm(data=request.GET)
    return render(request,'index.html',{
      'form': form
    })

  def post(self,request):
    form = MessageForm(data=request.POST)
    if form.is_valid():
      response = generate_pdf_response(context=form.cleaned_data)
      return response
    return redirect(reverse('pdf:message'))

編寫生成PDF響應response

view.py這裡為了方便直接把處理函式寫到檢視函式的檔案裡

def link_callback(uri):
  if uri.startswith(settings.MEDIA_URL):
    path = os.path.join(settings.MEDIA_ROOT,uri.replace(settings.MEDIA_URL,""))
  elif uri.startswith(settings.STATIC_URL):
    path = os.path.join(settings.STATIC_ROOT,uri.replace(settings.STATIC_URL,""))
  else:
    return uri

  # 確保本地檔案存在
  if not os.path.isfile(path):
    raise Exception(
      "Media URI 必須以以下格式開頭"
      f"'{settings.MEDIA_URL}' or '{settings.STATIC_URL}'")

  return path


def generate_pdf_response(context):
  response = HttpResponse(content_type="application/pdf")
  response["Content-Disposition"] = \
    f"attachment; filename='{context['name']}.pdf'"

  html = render_to_string("pdf.html",context=context)
  status = pisa.CreatePDF(html,dest=response,link_callback=link_callback)

  if status.err:
    return HttpResponse("PDF檔案生成失敗")
  return response

解決中文亂碼問題

需要下載中文字型msyh.ttf放在static目錄下的font目錄,用來設定全域性字型。這些檔案都在github倉庫裡。

def font_patch():
  from reportlab.pdfbase.ttfonts import TTFont
  from reportlab.pdfbase import pdfmetrics
  from xhtml2pdf.default import DEFAULT_FONT
  pdfmetrics.registerFont(TTFont('yh','{}/font/msyh.ttf'.format(
    settings.STATICFILES_DIRS[0])))
  DEFAULT_FONT['helvetica'] = 'yh'

把這個函式放在生成PDF響應前

按照以上大致步驟大家就能夠生成PDF檔案了,可以在網頁中瀏覽、放大、縮小,也可以下載,非常方便、簡單。

大家可以直接clone一份程式碼試試效果

以上這篇Django生成PDF文件顯示網頁上以及PDF中文顯示亂碼的解決方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。