Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法


Posted in Python onDecember 17, 2019

项目地址:https://github.com/PythonerKK/django-generate-pdf/tree/master

这个demo实现了通过用户输入自己的个人信息生成一份简历pdf,来阐述如何使用Django的HttpResponse生成PDF的文档。

先上效果图:

Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法

Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法

Django生成PDF文档显示网页上以及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响应前

Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法

按照以上大致步骤大家就能够生成PDF文件了,可以在网页中浏览、放大、缩小,也可以下载,非常方便、简单。

大家可以直接clone一份代码试试效果

以上这篇Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python内置数据类型详解
Aug 18 Python
python字典基本操作实例分析
Jul 11 Python
Python中pygame安装方法图文详解
Nov 11 Python
在windows下快速搭建web.py开发框架方法
Apr 22 Python
从零开始学Python第八周:详解网络编程基础(socket)
Dec 14 Python
Python数据分析之双色球基于线性回归算法预测下期中奖结果示例
Feb 08 Python
python自动发送邮件脚本
Jun 20 Python
解决Django layui {{}}冲突的问题
Aug 29 Python
解决pycharm同一目录下无法import其他文件
Feb 12 Python
django之导入并执行自定义的函数模块图解
Apr 01 Python
Django Model中字段(field)的各种选项说明
May 19 Python
PyCharm 2020.2下配置Anaconda环境的方法步骤
Sep 23 Python
Django对接支付宝实现支付宝充值金币功能示例
Dec 17 #Python
Django后端发送小程序微信模板消息示例(服务通知)
Dec 17 #Python
Django项目使用ckeditor详解(不使用admin)
Dec 17 #Python
python主线程与子线程的结束顺序实例解析
Dec 17 #Python
Django通用类视图实现忘记密码重置密码功能示例
Dec 17 #Python
Django集成celery发送异步邮件实例
Dec 17 #Python
python学生信息管理系统实现代码
Dec 17 #Python
You might like
谈谈新手如何学习PHP
2006/12/14 PHP
PHP函数utf8转gb2312编码
2006/12/21 PHP
php 根据url自动生成缩略图并处理高并发问题
2014/01/23 PHP
PHP版QQ互联OAuth示例代码分享
2015/07/05 PHP
PHP实现适用于文件内容操作的分页类
2016/06/15 PHP
通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法
2020/04/02 PHP
chrome原生方法之数组
2011/11/30 Javascript
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
2013/01/25 Javascript
JS格式化数字金额用逗号隔开保留两位小数
2013/10/18 Javascript
JavaScript的常见兼容问题及相关解决方法(chrome/IE/firefox)
2013/12/31 Javascript
JS获取iframe中longdesc属性的方法
2015/04/01 Javascript
js中的 || 与 && 运算符详解
2018/05/24 Javascript
layui radio点击事件实现input显示和隐藏的例子
2019/09/02 Javascript
微信小程序select下拉框实现源码
2019/11/08 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
2020/02/07 Javascript
vue.js实现简单的计算器功能
2020/02/22 Javascript
vue element 关闭当前tab 跳转到上一路由操作
2020/07/22 Javascript
[01:01:24]LGD vs Fnatic 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python中使用Flask、MongoDB搭建简易图片服务器
2015/02/04 Python
使用Python导出Excel图表以及导出为图片的方法
2015/11/07 Python
python运行其他程序的实现方法
2017/07/14 Python
Python实现的多进程和多线程功能示例
2018/05/29 Python
python实现决策树分类(2)
2018/08/30 Python
Python帮你识破双11的套路
2019/11/11 Python
Jupyter notebook设置背景主题,字体大小及自动补全代码的操作
2020/04/13 Python
css3如何绘制一个圆圆的loading转圈动画
2018/01/09 HTML / CSS
解锁canvas导出图片跨域的N种姿势小结
2019/01/24 HTML / CSS
英国独特礼物想法和个性化礼物网站:notonthehighstreet.com
2018/04/16 全球购物
adidas泰国官网:adidas TH
2020/07/11 全球购物
2014老师三严三实对照检查材料思想汇报
2014/09/18 职场文书
2014领导班子正风肃纪思想汇报
2014/09/18 职场文书
2014年前台接待工作总结
2014/12/05 职场文书
幼儿园安全工作总结2015
2015/04/20 职场文书
2015年学生会主席工作总结
2015/04/21 职场文书
千手观音观后感
2015/06/03 职场文书
保险公司增员口号
2015/12/25 职场文书