Django生成PDF文檔顯示在網頁上以及解決PDF中文顯示亂碼的問題

項目地址:https://github.com/PythonerKK/django-generate-pdf/tree/masterhtml

這個demo實現了經過用戶輸入本身的我的信息生成一份簡歷pdf,來闡述如何使用Django的HttpResponse生成PDF的文檔。python

先上效果圖:
git

安裝依賴庫

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

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構建,代碼更簡潔django

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這裏爲了方便直接把處理函數寫到視圖函數的文件裏app

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響應前
在這裏插入圖片描述post

按照以上大體步驟你們就可以生成PDF文件了,能夠在網頁中瀏覽、放大、縮小,也能夠下載,很是方便、簡單。
你們能夠直接clone一份代碼試試效果
項目地址:https://github.com/PythonerKK/django-generate-pdf/tree/master
我的網頁:https://liyuankun.cn字體

相關文章
相關標籤/搜索