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实现在字符串中查找子字符串的方法
Jul 11 Python
git进行版本控制心得详谈
Dec 10 Python
Python之reload流程实例代码解析
Jan 29 Python
Python Pywavelet 小波阈值实例
Jan 09 Python
PyQt5实现QLineEdit添加clicked信号的方法
Jun 25 Python
浅谈Python小波分析库Pywavelets的一点使用心得
Jul 09 Python
Django app配置多个数据库代码实例
Dec 17 Python
python 两种方法修改文件的创建时间、修改时间、访问时间
Sep 26 Python
python中的yield from语法快速学习
Nov 06 Python
Ubuntu16安装Python3.9的实现步骤
Dec 15 Python
基于注解实现 SpringBoot 接口防刷的方法
Mar 02 Python
Matplotlib绘制条形图的方法你知道吗
Mar 21 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
PHP 加密/解密函数 dencrypt(动态密文,带压缩功能,支持中文)
2009/01/30 PHP
php面象对象数据库操作类实例
2014/12/02 PHP
[原创]PHP实现逐行删除文件右侧空格的方法
2015/12/25 PHP
php+MySql实现登录系统与输出浏览者信息功能
2016/07/01 PHP
js计数器代码
2006/11/04 Javascript
心扬JS分页函数代码
2010/09/10 Javascript
解决jquery的.animate()函数在IE6下的问题
2010/12/03 Javascript
JS 有趣的eval优化输入验证实例代码
2013/09/22 Javascript
javascript实现限制上传文件大小
2015/02/06 Javascript
jquery+css3实现会动的小圆圈效果
2016/01/27 Javascript
jQuery使用正则表达式替换dom元素标签用法示例
2017/01/16 Javascript
Node.js设置CORS跨域请求中多域名白名单的方法
2017/03/28 Javascript
ES6新特性之Symbol类型用法分析
2017/03/31 Javascript
详解JS中的柯里化(currying)
2017/08/17 Javascript
Vue-cli项目获取本地json文件数据的实例
2018/03/07 Javascript
setTimeout时间设置为0详细解析
2018/03/13 Javascript
js遍历添加栏目类添加css 再点击其它删除css【推荐】
2018/06/12 Javascript
Vue实现兄弟组件间的联动效果
2020/01/21 Javascript
支付宝小程序实现省市区三级联动
2020/06/21 Javascript
vue 公共列表选择组件,引用Vant-UI的样式方式
2020/11/02 Javascript
python中ConfigParse模块的用法
2014/09/29 Python
Python下使用Psyco模块优化运行速度
2015/04/05 Python
python进程管理工具supervisor的安装与使用教程
2017/09/05 Python
Python中对数组集进行按行打乱shuffle的方法
2018/11/08 Python
详解python中自定义超时异常的几种方法
2019/07/29 Python
小学生打架检讨书
2014/01/26 职场文书
销售人员自我评价
2014/02/01 职场文书
求职信模板标准格式范文
2014/02/23 职场文书
社区娱乐活动方案
2014/08/21 职场文书
警察群众路线整改措施
2014/09/26 职场文书
2014年护士工作总结范文
2014/11/11 职场文书
学前班语言教学计划
2015/01/20 职场文书
公司保密管理制度
2015/08/04 职场文书
用Python简陋模拟n阶魔方
2021/04/17 Python
Vue如何实现组件间通信
2021/05/15 Vue.js
在Python 中将类对象序列化为JSON
2022/04/06 Python