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实现一个简单的MySQL类
Jan 07 Python
Python数据结构与算法之列表(链表,linked list)简单实现
Oct 30 Python
Redis使用watch完成秒杀抢购功能的代码
May 07 Python
详解Python中的分组函数groupby和itertools)
Jul 11 Python
不知道这5种下划线的含义,你就不算真的会Python!
Oct 09 Python
python f-string式格式化听语音流程讲解
Jun 18 Python
python处理excel绘制雷达图
Oct 18 Python
python将时分秒转换成秒的实例
Dec 07 Python
python实现局域网内实时通信代码
Dec 22 Python
python字符串下标与切片及使用方法
Feb 13 Python
jupyter notebook oepncv 显示一张图像的实现
Apr 24 Python
在Python中如何使用yield
Jun 07 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自定义加密与解密程序实例
2014/12/31 PHP
php设计模式之单例模式代码
2016/06/11 PHP
爆炸式的JS圆形浮动菜单特效代码
2010/03/03 Javascript
js 通用订单代码
2013/12/23 Javascript
JavaScript继承基础讲解(原型链、借用构造函数、混合模式、原型式继承、寄生式继承、寄生组合式继承)
2014/08/16 Javascript
JavaScript中操作字符串之localeCompare()方法的使用
2015/06/06 Javascript
超赞的动手创建JavaScript框架的详细教程
2015/06/30 Javascript
AngularJS删除路由中的#符号的方法
2016/09/20 Javascript
IE8利用自带的setCapture和releaseCapture解决iframe的拖拽事件方法
2016/10/25 Javascript
给easyui的datebox控件添加清空按钮的实现方法
2016/11/09 Javascript
详解js的事件代理(委托)
2016/12/22 Javascript
深入对Vue.js $watch方法的理解
2017/03/20 Javascript
JavaScript使用原型和原型链实现对象继承的方法详解
2017/04/05 Javascript
微信小程序表单验证错误提示效果
2017/05/19 Javascript
详解Vue基于 Nuxt.js 实现服务端渲染(SSR)
2018/04/05 Javascript
Mint-UI时间组件起始时间问题及时间插件使用
2018/08/20 Javascript
Vue 指令实现按钮级别权限管理功能
2019/04/23 Javascript
vue实现多条件和模糊搜索功能
2019/05/28 Javascript
vue语法自动转typescript(解放双手)
2019/09/18 Javascript
微信小程序实现上传多个文件 超过10个
2020/03/30 Javascript
Python基础中所出现的异常报错总结
2016/11/19 Python
Python 专题二 条件语句和循环语句的基础知识
2017/03/19 Python
python同时替换多个字符串方法示例
2019/09/17 Python
python 实现二维列表转置
2019/12/02 Python
Python tkinter三种布局实例详解
2020/01/06 Python
python学习将数据写入文件并保存方法
2020/06/07 Python
python实现在列表中查找某个元素的下标示例
2020/11/16 Python
全球在线商店:BerryLook
2019/04/14 全球购物
工程业务员工作职责
2013/12/07 职场文书
企业委托书范本
2014/09/13 职场文书
2014年工人工作总结
2014/11/25 职场文书
大学生英文求职信范文
2015/03/19 职场文书
python使用pygame创建精灵Sprite
2021/04/06 Python
MySQL中存储时间的最佳实践指南
2021/07/01 MySQL
PostgreSQL解析URL的方法
2021/08/02 PostgreSQL
nginx中proxy_pass各种用法详解
2021/11/07 Servers