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基于Tkinter实现的记事本实例
Jun 17 Python
python如何通过protobuf实现rpc
Mar 06 Python
Python中函数参数设置及使用的学习笔记
May 03 Python
python 字符串转列表 list 出现\ufeff的解决方法
Jun 22 Python
Python实现判断给定列表是否有重复元素的方法
Apr 11 Python
Python图像处理之图像的缩放、旋转与翻转实现方法示例
Jan 04 Python
浅谈Python的条件判断语句if/else语句
Mar 21 Python
Python数据存储之 h5py详解
Dec 26 Python
git查看、创建、删除、本地、远程分支方法详解
Feb 18 Python
Django模板之基本的 for 循环 和 List内容的显示方式
Mar 31 Python
python 实现倒计时功能(gui界面)
Nov 11 Python
python中的插入排序的简单用法
Jan 19 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控制linux服务器常用功能 关机 重启 开新站点等
2012/09/05 PHP
PHP正则表达式笔记与实例详解
2019/05/09 PHP
javascript 禁止复制网页
2009/06/11 Javascript
JavaScript 拾漏补遗
2009/12/27 Javascript
javascript中的parseInt和parseFloat区别
2013/07/12 Javascript
javascript预加载图片、css、js的方法示例介绍
2013/10/14 Javascript
JS简单操作select和dropdownlist实例
2014/11/26 Javascript
在easyUI开发中,出现jquery.easyui.min.js函数库问题的解决办法
2015/09/11 Javascript
jQuery的框架介绍
2016/05/11 Javascript
全面解析JavaScript中apply和call以及bind(推荐)
2016/06/15 Javascript
jQuery插件fullPage.js实现全屏滚动效果
2016/12/02 Javascript
js手机号4位显示空格,银行卡每4位显示空格效果
2017/03/23 Javascript
微信小程序 下拉菜单简单实例
2017/04/13 Javascript
nodejs操作mongodb的填删改查模块的制作及引入实例
2018/01/02 NodeJs
JavaScript中创建原子的方法总结
2018/08/26 Javascript
使用angularjs.foreach时return的问题解决
2018/09/30 Javascript
vue基于element-ui的三级CheckBox复选框功能的实现代码
2018/10/15 Javascript
Vue使用.sync 实现父子组件的双向绑定数据问题
2019/04/04 Javascript
vue 验证码界面实现点击后标灰并设置div按钮不可点击状态
2019/10/28 Javascript
[02:20]DOTA2中文配音宣传片
2013/05/22 DOTA
[54:24]Optic vs TNC 2018国际邀请赛小组赛BO2 第二场
2018/08/18 DOTA
Python的Tornado框架的异步任务与AsyncHTTPClient
2016/06/27 Python
Python绘制3d螺旋曲线图实例代码
2017/12/20 Python
Python实现简单生成验证码功能【基于random模块】
2018/02/10 Python
python+flask实现API的方法
2018/11/21 Python
Django中使用Celery的方法示例
2018/11/29 Python
python基础 range的用法解析
2019/08/23 Python
对pytorch的函数中的group参数的作用介绍
2020/02/18 Python
Python基于pandas绘制散点图矩阵代码实例
2020/06/04 Python
TCP/IP的分层模型
2013/10/27 面试题
应届毕业生个人自荐信范文
2013/11/30 职场文书
师范生求职自荐信
2014/06/14 职场文书
交通安全主题班会
2015/08/12 职场文书
暑假生活随笔
2015/08/15 职场文书
SpringBoot整合JWT的入门指南
2021/06/29 Java/Android
Mysql 一主多从的部署
2022/05/20 MySQL