zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Java实现 LeetCode 343 整数拆分(动态规划入门经典)
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 342 4的幂
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 341 扁平化嵌套列表迭代器
    Java实现 LeetCode 338 比特位计数
    H264(NAL简介与I帧判断)
    分享一段H264视频和AAC音频的RTP封包代码
  • 原文地址:https://www.cnblogs.com/PyKK2019/p/11129471.html
Copyright © 2011-2022 走看看