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正则表达式教程之一:基础篇
Mar 02 Python
Python tkinter事件高级用法实例
Jan 31 Python
python解析含有重复key的json方法
Jan 22 Python
python面向对象法实现图书管理系统
Apr 19 Python
Python实现的栈、队列、文件目录遍历操作示例
May 06 Python
TensorFlow tf.nn.max_pool实现池化操作方式
Jan 04 Python
win10安装tensorflow-gpu1.8.0详细完整步骤
Jan 20 Python
python3格式化字符串 f-string的高级用法(推荐)
Mar 04 Python
django queryset相加和筛选教程
May 18 Python
linux系统下pip升级报错的解决方法
Jan 31 Python
python实现代码审查自动回复消息
Feb 01 Python
Python Django / Flask如何使用Elasticsearch
Apr 19 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
暴雪前总裁遗憾:没尽早追赶Dota 取消星际争霸幽灵
2020/03/08 星际争霸
php+jquery+html实现点击不刷新加载更多的实例代码
2016/08/12 PHP
JavaScript Event学习第十章 一些可替换的事件对
2010/02/10 Javascript
javascript 弹出窗口中是否显示地址栏的实现代码
2011/04/14 Javascript
JavaScript检测字符串中是否含有html标签实现方法
2015/07/01 Javascript
jQuery UI结合Ajax创建可定制的Web界面
2016/06/22 Javascript
原生JS实现轮播效果+学前端的感受(防止走火入魔)
2016/08/21 Javascript
JS查找英文文章中出现频率最高的单词
2017/03/20 Javascript
JavaScript之promise_动力节点Java学院整理
2017/07/03 Javascript
深入探究node之Transform
2017/07/20 Javascript
详解Vue SPA项目优化小记
2018/07/03 Javascript
多个vue子路由文件自动化合并的方法
2019/09/03 Javascript
在Python中实现贪婪排名算法的教程
2015/04/17 Python
python中list列表的高级函数
2016/05/17 Python
pandas数据筛选和csv操作的实现方法
2019/07/02 Python
python入门之基础语法学习笔记
2020/02/08 Python
Jupyter加载文件的实现方法
2020/04/14 Python
Python基于Hypothesis测试库生成测试数据
2020/04/29 Python
matplotlib 画双轴子图无法显示x轴的解决方法
2020/07/27 Python
matplotlib基础绘图命令之imshow的使用
2020/08/13 Python
Python通过fnmatch模块实现文件名匹配
2020/09/30 Python
python自动打开浏览器下载zip并提取内容写入excel
2021/01/04 Python
奥斯汀独木舟和皮划艇:Austin Canoe & Kayak
2018/05/22 全球购物
印尼购物网站:iLOTTE
2019/10/16 全球购物
带薪年假请假条
2014/02/04 职场文书
2014年团支书工作总结
2014/11/14 职场文书
军训个人总结
2015/03/03 职场文书
2015年销售工作总结范文
2015/03/30 职场文书
学校捐书倡议书
2015/04/27 职场文书
社区党务工作总结2015
2015/05/19 职场文书
2015年小班保育员工作总结
2015/05/27 职场文书
天鹅湖观后感
2015/06/09 职场文书
新闻稿标题
2015/07/18 职场文书
2015年十月一日放假通知
2015/08/18 职场文书
小学班主任研修日志
2015/11/13 职场文书
深入解析MySQL索引数据结构
2021/10/16 MySQL