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 相关文章推荐
使用Python3中的gettext模块翻译Python源码以支持多语言
Mar 31 Python
python制作爬虫并将抓取结果保存到excel中
Apr 06 Python
numpy排序与集合运算用法示例
Dec 15 Python
快速解决安装python没有scripts文件夹的问题
Apr 03 Python
Python实现八皇后问题示例代码
Dec 09 Python
Python+OpenCV图片局部区域像素值处理改进版详解
Jan 23 Python
一个可以套路别人的python小程序实例代码
Apr 09 Python
用Python实现二叉树、二叉树非递归遍历及绘制的例子
Aug 09 Python
python 一维二维插值实例
Apr 22 Python
详解如何修改python中字典的键和值
Sep 29 Python
python 基于Apscheduler实现定时任务
Dec 15 Python
Python批量将csv文件转化成xml文件的实例
May 10 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
Yii调试SQL的常用方法
2014/07/09 PHP
在Linux系统的服务器上隐藏PHP版本号的方法
2015/06/06 PHP
php使用curl详细解析及问题汇总
2016/08/11 PHP
php实现的统计字数函数定义与使用示例
2017/07/26 PHP
laravel执行php artisan migrate报错的解决方法
2019/10/09 PHP
JavaScript 参考教程
2006/12/29 Javascript
JavaScript 动态创建VML的方法
2009/10/14 Javascript
js Form.elements[i]的使用实例
2011/11/13 Javascript
jQuery修改li下的样式以及li下的img的src的值的方法
2014/11/02 Javascript
jQuery遍历页面所有CheckBox查看是否被选中的方法
2015/04/14 Javascript
Node.js编写爬虫的基本思路及抓取百度图片的实例分享
2016/03/12 Javascript
jQuery实现三级联动效果
2017/03/02 Javascript
Vue组件化通讯的实例代码
2017/06/23 Javascript
浅谈原生JS中的延迟脚本和异步脚本
2017/07/12 Javascript
利用adb shell和node.js实现抖音自动抢红包功能(推荐)
2018/02/22 Javascript
angularJs使用ng-repeat遍历后选中某一个的方法
2018/09/30 Javascript
JavaScript 中 JSON.parse 函数 和 JSON.stringify 函数
2018/12/05 Javascript
vue-cli系列之vue-cli-service整体架构浅析
2019/01/14 Javascript
vue轻量级框架无法获取到vue对象解决方法
2019/05/12 Javascript
vue接口请求加密实例
2020/08/11 Javascript
详解Vue的组件中data选项为什么必须是函数
2020/08/17 Javascript
[36:02]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第一局
2016/02/28 DOTA
python机器学习之神经网络(三)
2017/12/20 Python
快速了解python leveldb
2018/01/18 Python
python pillow模块使用方法详解
2019/08/30 Python
Merrell迈乐澳大利亚网站:购买户外登山鞋
2017/05/28 全球购物
Under Armour澳大利亚官网:美国知名的高端功能性运动品牌
2018/02/22 全球购物
LUISAVIAROMA中国官网:时尚奢侈品牌购物网站
2020/11/01 全球购物
Weblogic的布署方式
2013/08/23 面试题
5个HTML5的常用本地存储方式详解与介绍
2021/03/27 HTML / CSS
初中家长评语和期望
2014/12/26 职场文书
汽车4S店销售经理岗位职责
2015/04/02 职场文书
搞笑欢迎词大全
2015/09/30 职场文书
go select编译期的优化处理逻辑使用场景分析
2021/06/28 Golang
Apache POI的基本使用详解
2021/11/07 Servers
Pygame Time时间控制的具体使用详解
2021/11/17 Python