• 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

  • 相关阅读:
    福州KTV
    MSN登陆不上:微软谴责中国的“技术问题”
    DB2 存储过程开发最佳实践
    在DB2存储过程中返回一个数据集
    Host is not allowed to connect to this MySQL server 解决方案
    CentOS安装中文支持
    ImportError: libpq.so.5: cannot open shared object file: No such file or directory
    CentOS 终端显示中文异常解决办法
    pytestDemo
    python 获取当前运行的类名函数名
  • 原文地址:https://www.cnblogs.com/PyKK2019/p/11129471.html
Copyright © 2020-2023  润新知