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的批量远程管理和部署工具Fabric用法实例
Jan 23 Python
Python验证码识别的方法
Jul 10 Python
Python随机生成数据后插入到PostgreSQL
Jul 28 Python
Django内容增加富文本功能的实例
Oct 17 Python
Python爬取十篇新闻统计TF-IDF
Jan 03 Python
如何在Django中添加没有微秒的 DateTimeField 属性详解
Jan 30 Python
对pyqt5多线程正确的开启姿势详解
Jun 14 Python
Python 获取 datax 执行结果保存到数据库的方法
Jul 11 Python
Tensorflow实现神经网络拟合线性回归
Jul 19 Python
django 多数据库及分库实现方式
Apr 01 Python
django实现后台显示媒体文件
Apr 07 Python
Python 可迭代对象 iterable的具体使用
Aug 07 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
PHP6 mysql连接方式说明
2009/02/09 PHP
PHP 中文处理技巧
2010/04/25 PHP
PHP 5.5 创建和验证哈希最简单的方法详解
2013/11/07 PHP
php实现水仙花数示例分享
2014/04/03 PHP
四种php中webservice实现的简单架构方法及实例
2015/02/03 PHP
PHP 数据结构队列(SplQueue)和优先队列(SplPriorityQueue)简单使用实例
2015/05/12 PHP
Adnroid 微信内置浏览器清除缓存
2016/07/11 PHP
PHP实现微信模拟登陆并给用户发送消息的方法【文字,图片,图文】
2017/06/29 PHP
yii2 上传图片的示例代码
2018/11/02 PHP
PHP命名空间与自动加载机制的基础介绍
2019/08/25 PHP
js解析与序列化json数据(三)json的解析探讨
2013/02/01 Javascript
jQuery之折叠面板的深入解析
2013/06/19 Javascript
jquery ajax请求方式与提示用户正在处理请稍等
2014/09/01 Javascript
JavaScript检测上传文件大小的方法
2015/07/22 Javascript
JavaScript知识点总结之如何提高性能
2016/01/15 Javascript
jQuery用noConflict代替$的实现方法
2017/04/12 jQuery
nuxt+axios解决前后端分离SSR的示例代码
2017/10/24 Javascript
前端性能优化建议
2020/09/17 Javascript
[06:38]DOTA2怒掀电竞风暴 2013Chinajoy
2013/07/27 DOTA
[45:50]完美世界DOTA2联赛PWL S3 CPG vs Forest 第二场 12.16
2020/12/17 DOTA
Python 判断文件或目录是否存在的实例代码
2018/07/19 Python
python使用sessions模拟登录淘宝的方式
2019/08/16 Python
python 命令行传入参数实现解析
2019/08/30 Python
python错误调试及单元文档测试过程解析
2019/12/19 Python
Python函数的定义方式与函数参数问题实例分析
2019/12/26 Python
PyQt5通过信号实现MVC的示例
2021/02/06 Python
Html5 localStorage入门教程
2018/04/26 HTML / CSS
Lacoste美国官网:经典POLO衫品牌
2016/10/12 全球购物
行政主管岗位职责
2013/11/18 职场文书
财务与信息服务专业推荐信
2013/11/28 职场文书
国际金融专业大学生职业生涯规划书
2013/12/28 职场文书
优秀的2014年两会精神解读
2014/03/17 职场文书
玄武湖导游词
2015/02/05 职场文书
五一劳动节慰问信
2015/02/14 职场文书
村官个人总结范文
2015/03/03 职场文书
食品仓管员岗位职责
2015/04/01 职场文书