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 25 Python
python随机生成指定长度密码的方法
Apr 04 Python
详细探究Python中的字典容器
Apr 14 Python
在Debian下配置Python+Django+Nginx+uWSGI+MySQL的教程
Apr 25 Python
Python 中开发pattern的string模板(template) 实例详解
Apr 01 Python
Python用sndhdr模块识别音频格式详解
Jan 11 Python
利用Pyhton中的requests包进行网页访问测试的方法
Dec 26 Python
Python2与Python3的区别实例分析
Apr 11 Python
基于Python生成个性二维码过程详解
Mar 05 Python
Python中操作各种多媒体,视频、音频到图片的代码详解
Jun 04 Python
如何用Anaconda搭建虚拟环境并创建Django项目
Aug 02 Python
聊聊python在linux下与windows下导入模块的区别说明
Mar 03 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 checkdate、getdate等日期时间函数操作详解
2010/03/11 PHP
php小技巧 把数组的键和值交换形成了新的数组,查找值取得键
2011/06/02 PHP
thinkPHP中钩子的两种配置调用方法详解
2016/11/11 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
2020/02/15 PHP
js获取单元格自定义属性值的代码(IE/Firefox)
2010/04/05 Javascript
Javascript中的相等与不等运算
2010/04/25 Javascript
JavaScript中的正则表达式简明总结
2014/04/04 Javascript
JavaScript实现简单图片滚动附源码下载
2014/06/17 Javascript
jQuery焦点图轮播特效代码分享(3款)
2015/09/05 Javascript
jQuery基于扩展实现的倒计时效果
2016/05/14 Javascript
JavaScript实现的微信二维码图片生成器的示例
2016/10/26 Javascript
JavaScript实现换肤功能
2017/09/15 Javascript
vue使用axios时关于this的指向问题详解
2017/12/22 Javascript
vue如何将v-for中的表格导出来
2018/05/07 Javascript
详解基于Node.js的HTTP/2 Server实践
2018/05/31 Javascript
Vue.js实现数据响应的方法
2018/08/13 Javascript
浅谈Vue组件及组件的注册方法
2018/08/24 Javascript
微信小程序自定义底部导航带跳转功能
2018/11/27 Javascript
微信小程序加载机制及运行机制图解
2019/11/27 Javascript
vue实现可移动的悬浮按钮
2021/03/04 Vue.js
[00:43]FTP典藏礼包 DOTA2三大英雄霸气新套装
2014/03/21 DOTA
[02:49]2018DOTA2亚洲邀请赛主赛事决赛日战况回顾 Mineski鏖战5局夺得辉耀
2018/04/10 DOTA
详解Python发送邮件实例
2016/01/10 Python
Python中文编码知识点
2019/02/18 Python
Python StringIO如何在内存中读写str
2020/01/07 Python
python读取csv文件指定行的2种方法详解
2020/02/13 Python
如何使用python的ctypes调用医保中心的dll动态库下载医保中心的账单
2020/05/24 Python
GEOX鞋美国官方网站:意大利会呼吸的鞋
2017/07/12 全球购物
英国时尚优质的女装:Hope Fashion
2018/08/14 全球购物
日本即尚网:JSHOPPERS.com(支持中文)
2019/12/03 全球购物
九年级语文教学反思
2014/02/04 职场文书
不打扫卫生检讨书
2014/02/12 职场文书
2014派出所所长群众路线对照检查材料思想汇报
2014/09/18 职场文书
县级领导干部开展党的群众路线教育实践活动工作汇报
2014/10/25 职场文书
八一建军节主持词
2015/07/01 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书