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 写的一个爬虫程序源码
Feb 28 Python
Python 基础教程之闭包的使用方法
Sep 29 Python
python版学生管理系统
Jan 10 Python
django模板结构优化的方法
Feb 28 Python
django ModelForm修改显示缩略图 imagefield类型的实例
Jul 28 Python
python实现批量修改服务器密码的方法
Aug 13 Python
Python字节单位转换实例
Dec 05 Python
Python + Requests + Unittest接口自动化测试实例分析
Dec 12 Python
Python函数式编程实例详解
Jan 17 Python
利用Python实现字幕挂载(把字幕文件与视频合并)思路详解
Oct 21 Python
Pandas数据分析的一些常用小技巧
Feb 07 Python
Python通过loop.run_in_executor执行同步代码 同步变为异步
Apr 11 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
利用中国天气预报接口实现简单天气预报
2014/01/20 PHP
PHP的拦截器实例分析
2014/11/03 PHP
php原生导出excel文件的两种方法(推荐)
2016/11/19 PHP
PHP观察者模式实例分析【对比JS观察者模式】
2019/05/22 PHP
javascript检测浏览器的缩放状态实现代码
2014/09/28 Javascript
基于Jquery实现万圣节快乐特效
2015/11/01 Javascript
WordPress中鼠标悬停显示和隐藏评论及引用按钮的实现
2016/01/12 Javascript
利用AJAX实现WordPress中的文章列表及评论的分页功能
2016/05/17 Javascript
JQuery Mobile 弹出式登录框的实现方法
2016/05/28 Javascript
Chrome浏览器的alert弹窗禁止再次弹出后恢复的方法
2016/12/30 Javascript
利用js的闭包原理做对象封装及调用方法
2017/04/07 Javascript
layui.js实现的表单验证功能示例
2017/11/15 Javascript
利用es6 new.target来对模拟抽象类的方法
2019/05/10 Javascript
微信小程序嵌入腾讯视频源过程详解
2019/08/08 Javascript
谈谈我在vue-cli3中用预渲染遇到的坑
2020/04/22 Javascript
python线程锁(thread)学习示例
2013/12/04 Python
python发送HTTP请求的方法小结
2015/07/08 Python
Python中音频处理库pydub的使用教程
2017/06/07 Python
Python数据结构之顺序表的实现代码示例
2017/11/15 Python
python判断一个集合是否为另一个集合的子集方法
2018/05/04 Python
Python决策树之基于信息增益的特征选择示例
2018/06/25 Python
Python爬虫PyQuery库基本用法入门教程
2018/08/04 Python
Python使用修饰器进行异常日志记录操作示例
2019/03/19 Python
茱莉蔻美国官网:Jurlique美国
2020/11/24 全球购物
澳大利亚女装精品店:Alannah Hill
2020/07/29 全球购物
就业推荐自我鉴定
2013/10/06 职场文书
销售部主管岗位职责
2013/12/18 职场文书
座谈会主持词
2014/03/20 职场文书
《灰椋鸟》教学反思
2014/04/27 职场文书
青春无悔演讲稿
2014/05/08 职场文书
学校安全工作汇报材料
2014/08/16 职场文书
质量保证书格式模板
2015/02/27 职场文书
离婚起诉书范本
2015/05/18 职场文书
go结构体嵌套的切片数组操作
2021/04/28 Golang
Zabbix对Kafka topic积压数据监控的问题(bug优化)
2022/07/07 Servers
Nginx如何配置多个服务域名解析共用80端口详解
2022/09/23 Servers