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中IPYTHON入门实例
May 11 Python
python从网络读取图片并直接进行处理的方法
May 22 Python
Python算法输出1-9数组形成的结果为100的所有运算式
Nov 03 Python
详解supervisor使用教程
Nov 21 Python
Python编程求解二叉树中和为某一值的路径代码示例
Jan 04 Python
Django 2.0版本的新特性抢先看!
Jan 05 Python
使用Django和Python创建Json response的方法
Mar 26 Python
对python中Json与object转化的方法详解
Dec 31 Python
Python实现 版本号对比功能的实例代码
Apr 18 Python
Selenium常见异常解析及解决方案示范
Apr 10 Python
python 比较字典value的最大值的几种方法
Apr 17 Python
虚拟机下载python是否需要联网
Jul 27 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生成随机数或者字符串的代码
2008/09/05 PHP
php使浏览器直接下载pdf文件的方法
2013/11/15 PHP
使用gd库实现php服务端图片裁剪和生成缩略图功能分享
2013/12/25 PHP
PHP的preg_match匹配字符串长度问题解决方法
2014/05/03 PHP
destoon供应信息title调用出公司名称的方法
2014/08/22 PHP
PHP利用func_get_args和func_num_args函数实现函数重载实例
2014/11/12 PHP
php过滤htmlspecialchars() 函数实现把预定义的字符转换为 HTML 实体用法分析
2019/06/25 PHP
thinkphp5.1框架模板赋值与变量输出示例
2020/05/25 PHP
用javascript实现点击链接弹出"图片另存为"而不是直接打开
2007/08/15 Javascript
jquery的extend和fn.extend的使用说明
2011/01/09 Javascript
JavaScript flash复制库类 Zero Clipboard
2011/01/17 Javascript
js nextSibling属性和previousSibling属性概述及使用注意
2013/02/16 Javascript
使用GruntJS链接与压缩多个JavaScript文件过程详解
2013/08/02 Javascript
使用jQuery实现input数值增量和减量的方法
2015/01/24 Javascript
jQuery实现点击按钮文字变成input框点击保存变成文字
2016/05/09 Javascript
js流动式效果显示当前系统时间
2016/05/16 Javascript
JavaScript实现离开页面前提示功能【附jQuery实现方法】
2017/09/26 jQuery
JS中this的指向以及call、apply的作用
2018/05/06 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
2018/12/05 Javascript
Ant-design-vue Table组件customRow属性的使用说明
2020/10/28 Javascript
python实现探测socket和web服务示例
2014/03/28 Python
Python多进程并发(multiprocessing)用法实例详解
2015/06/02 Python
浅谈python类属性的访问、设置和删除方法
2016/07/25 Python
在IPython中进行Python程序执行时间的测量方法
2018/11/01 Python
详解python调用cmd命令三种方法
2019/07/08 Python
python定时任务 sched模块用法实例
2019/11/04 Python
OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现
2019/11/25 Python
浅谈Python中的字符串
2020/06/10 Python
CSS3中的transform属性进行2D和3D变换的基本用法
2016/05/12 HTML / CSS
香港太阳眼镜网上商店:SmartBuyGlasses香港
2016/07/22 全球购物
英国HYPE双肩包官网:英国本土时尚潮牌
2018/09/26 全球购物
The Hut英国:英国领先的豪华在线百货商店
2019/07/26 全球购物
奥地利手表、香水、化妆品和珠宝购物网站:Brasty.at
2021/01/17 全球购物
治理商业贿赂工作总结
2015/08/10 职场文书
Canvas如何做个雪花屏版404的实现
2021/09/25 HTML / CSS
css中有哪些方式可以隐藏页面元素及区别
2022/06/16 HTML / CSS