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一份代碼試試效果
項目地址:https://github.com/PythonerKK/django-generate-pdf/tree/master
個人網頁:https://liyuankun.cn


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM