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 相关文章推荐
仅用50行Python代码实现一个简单的代理服务器
Apr 08 Python
Windows下PyMongo下载及安装教程
Apr 27 Python
Python的Bottle框架中实现最基本的get和post的方法的教程
Apr 30 Python
利用Django内置的认证视图实现用户密码重置功能详解
Nov 24 Python
Python简单计算数组元素平均值的方法示例
Dec 26 Python
Django使用Celery异步任务队列的使用
Mar 13 Python
Django使用HttpResponse返回图片并显示的方法
May 22 Python
python读取LMDB中图像的方法
Jul 02 Python
Python3安装psycopy2以及遇到问题解决方法
Jul 03 Python
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
Jul 04 Python
Django 自动生成api接口文档教程
Nov 19 Python
python使用HTMLTestRunner导出饼图分析报告的方法
Dec 30 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
WINDOWS服务器安装多套PHP的另类解决方案
2006/10/09 PHP
浅析php如何实现App常用的秒发功能
2016/08/03 PHP
PHP实现ASCII码与字符串相互转换的方法
2017/04/29 PHP
PHP PDOStatement::debugDumpParams讲解
2019/01/30 PHP
php 使用 __call实现重载功能示例
2019/11/18 PHP
js类中的公有变量和私有变量
2008/07/24 Javascript
用JQuery 判断某个属性是否存在hasAttr的解决方法
2013/04/26 Javascript
javascript实现博客园页面右下角返回顶部按钮
2015/02/22 Javascript
JavaScript模拟实现键盘打字效果
2015/06/29 Javascript
JavaScript 消息框效果【实现代码】
2016/04/27 Javascript
ichart.js绘制虚线、平均分虚线效果的实现代码
2016/05/05 Javascript
Three.js学习之Lamber材质和Phong材质
2016/08/04 Javascript
ajax图片上传,图片异步上传,更新实例
2016/12/30 Javascript
js遍历json对象所有key及根据动态key获取值的方法(必看)
2017/03/09 Javascript
node.js操作mongodb简单示例分享
2017/05/25 Javascript
学习JS中的DOM节点以及操作
2018/04/30 Javascript
JavaScript强制类型转换和隐式类型转换操作示例
2019/05/01 Javascript
[02:35]DOTA2超级联赛专访XB 难忘一年九冠称王
2013/06/20 DOTA
打印出python 当前全局变量和入口参数的所有属性
2009/07/01 Python
python 类对象和实例对象动态添加方法(分享)
2017/12/31 Python
简单实现python画圆功能
2018/01/25 Python
分享Pycharm中一些不为人知的技巧
2018/04/03 Python
python使用PyQt5的简单方法
2019/02/27 Python
Golang GBK转UTF-8的例子
2019/08/26 Python
pymysql模块的使用(增删改查)详解
2019/09/09 Python
Python计算不规则图形面积算法实现解析
2019/11/22 Python
Python3 解决读取中文文件txt编码的问题
2019/12/20 Python
Python中实现输入超时及如何通过变量获取变量名
2020/01/18 Python
python利用opencv保存、播放视频
2020/11/02 Python
英国豪华家具和经典家居饰品购物网站:OKA
2020/06/05 全球购物
告诉你怎样写创业计划书
2014/01/27 职场文书
演讲比赛的活动方案
2014/08/28 职场文书
第28个世界无烟日活动总结
2015/02/10 职场文书
七年级生物教学反思
2016/02/20 职场文书
少儿励志名言(80句)
2019/08/14 职场文书
Axios取消重复请求的方法实例详解
2021/06/15 Javascript