Django生成PDF文档显示在网页上以及解决PDF中文显示乱码的问题


Posted in Python onJuly 04, 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一份代码试试效果

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中实现字符串类型与字典类型相互转换的方法
Aug 18 Python
Python实现扫描局域网活动ip(扫描在线电脑)
Apr 28 Python
举例讲解Python中的迭代器、生成器与列表解析用法
Mar 20 Python
Python 模板引擎的注入问题分析
Jan 01 Python
理论讲解python多进程并发编程
Feb 09 Python
python实现自动解数独小程序
Jan 21 Python
基于python if 判断选择结构的实例详解
May 06 Python
python中sklearn的pipeline模块实例详解
May 21 Python
浅谈keras保存模型中的save()和save_weights()区别
May 21 Python
Django DRF路由与扩展功能的实现
Jun 03 Python
4种方法python批量修改替换列表中元素
Apr 07 Python
Python获取字典中某个key的value
Apr 13 Python
python批量修改图片尺寸,并保存指定路径的实现方法
Jul 04 #Python
python代理工具mitmproxy使用指南
Jul 04 #Python
Python批量修改图片分辨率的实例代码
Jul 04 #Python
Django 中自定义 Admin 样式与功能的实现方法
Jul 04 #Python
python3用PIL把图片转换为RGB图片的实例
Jul 04 #Python
python中比较两个列表的实例方法
Jul 04 #Python
一文秒懂python读写csv xml json文件各种骚操作
Jul 04 #Python
You might like
php实现的太平洋时间和北京时间互转的自定义函数分享
2014/08/19 PHP
PHP设计模式之观察者模式实例
2016/02/22 PHP
详解PHP5.6.30与Apache2.4.x配置
2017/06/02 PHP
PHP调用QQ互联接口实现QQ登录网站功能示例
2019/10/24 PHP
实现连缀调用的map方法(prototype)
2009/08/05 Javascript
js网页中的(运行代码)功能实现思路
2013/02/04 Javascript
JavaScript对Cookie进行读写操作实例
2015/07/25 Javascript
Jquery幻灯片特效代码分享--鼠标点击按钮时切换(1)
2015/08/15 Javascript
JavaScript数据推送Comet技术详解
2016/04/07 Javascript
angular ng-repeat数组中的数组实例
2017/02/18 Javascript
js事件冒泡与事件捕获详解
2017/02/20 Javascript
深入浅析JavaScript中的RegExp对象
2017/09/18 Javascript
echarts学习笔记之箱线图的分析与绘制详解
2017/11/22 Javascript
详解webpack 打包文件体积过大解决方案(code splitting)
2018/04/10 Javascript
页面点击小红心js实现代码
2018/05/26 Javascript
Express之托管静态文件的方法
2018/06/01 Javascript
Vue使用NProgress的操作过程解析
2019/10/10 Javascript
vue 父组件通过$refs获取子组件的值和方法详解
2019/11/07 Javascript
js实现移动端图片滑块验证功能
2020/09/29 Javascript
[17:45]DOTA2 HEROES教学视频教你分分钟做大人-军团指挥官
2014/06/11 DOTA
Python实现mysql数据库更新表数据接口的功能
2017/11/19 Python
对numpy的array和python中自带的list之间相互转化详解
2018/04/13 Python
python 利用栈和队列模拟递归的过程
2018/05/29 Python
pyttsx3实现中文文字转语音的方法
2018/12/24 Python
python字符串循环左移
2019/03/08 Python
python设计tcp数据包协议类的例子
2019/07/23 Python
Python3之乱码\xe6\x97\xa0\xe6\xb3\x95处理方式
2020/05/11 Python
基于Python爬虫采集天气网实时信息
2020/06/05 Python
django filter过滤器实现显示某个类型指定字段不同值方式
2020/07/16 Python
Python正则re模块使用步骤及原理解析
2020/08/18 Python
Python爬虫入门教程02之笔趣阁小说爬取
2021/01/24 Python
css3实例教程 一款纯css3实现的环形导航菜单
2014/10/20 HTML / CSS
杭州-飞时达软件有限公司.net笔面试
2012/04/28 面试题
计划生育宣传标语
2014/06/21 职场文书
我的中国梦演讲稿高中篇
2014/08/19 职场文书
Pytest中skip skipif跳过用例详解
2021/06/30 Python