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爬虫入门教程之糗百图片爬虫代码分享
Sep 02 Python
python使用多进程的实例详解
Sep 19 Python
Python二叉树的镜像转换实现方法示例
Mar 06 Python
Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】
Oct 12 Python
Python如何使用BeautifulSoup爬取网页信息
Nov 26 Python
pytorch实现保证每次运行使用的随机数都相同
Feb 20 Python
python numpy库linspace相同间隔采样的实现
Feb 25 Python
python定义类的简单用法
Jul 24 Python
Python实现文件压缩和解压的示例代码
Aug 12 Python
用Python提取PDF表格的方法
Apr 11 Python
基于Python和openCV实现图像的全景拼接详细步骤
Oct 05 Python
Django框架模板用法详解
Jun 10 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
星际初学者游戏中永远要做的事
2020/03/04 星际争霸
php学习笔记之基础知识
2014/11/08 PHP
php中socket通信机制实例详解
2015/01/03 PHP
php实现表单多按钮提交action的处理方法
2015/10/24 PHP
javascript form 验证函数 弹出对话框形式
2009/06/23 Javascript
jquery pagination插件实现无刷新分页代码
2009/10/13 Javascript
javascript attachEvent绑定多个事件执行顺序问题
2010/10/20 Javascript
js实现接收表单的值并将值拼在表单action后面的方法
2015/11/23 Javascript
javascript实现在网页中运行本地程序的方法
2016/02/03 Javascript
AngularJS Controller作用域
2017/01/09 Javascript
如何在 Vue.js 中使用第三方js库
2017/04/25 Javascript
JavaScript实现数字前补“0”的五种方法示例
2019/01/03 Javascript
Vue使用Canvas绘制图片、矩形、线条、文字,下载图片
2019/04/26 Javascript
js比较两个单独的数组或对象是否相等的实例代码
2019/04/28 Javascript
Vue filter 过滤当前时间 实现实时更新效果
2019/12/20 Javascript
Openlayers显示瓦片网格信息的方法
2020/09/28 Javascript
[34:27]DOTA2上海特级锦标赛B组败者赛 VG VS Spirit第一局
2016/02/26 DOTA
Python实现栈的方法
2015/05/26 Python
Python、PyCharm安装及使用方法(Mac版)详解
2017/04/28 Python
pandas进行数据的交集与并集方式的数据合并方法
2018/06/27 Python
对pycharm代码整体左移和右移缩进快捷键的介绍
2018/07/16 Python
如何爬取通过ajax加载数据的网站
2019/08/15 Python
pycharm 中mark directory as exclude的用法详解
2020/02/14 Python
python实现图片转字符画的完整代码
2021/02/21 Python
wordpress添加Html5的表单验证required方法小结
2020/08/18 HTML / CSS
巴西最大的体育用品商城:Netshoes巴西
2016/11/29 全球购物
跑步、骑行和铁人三项的高性能眼镜和服装:ROKA
2018/07/06 全球购物
伦敦新晋轻奢耳饰潮牌:Tada & Toy
2020/05/25 全球购物
面料业务员岗位职责
2013/12/26 职场文书
关于梦想的演讲稿
2014/05/05 职场文书
后备干部推荐材料
2014/12/24 职场文书
销售督导岗位职责
2015/04/10 职场文书
男人帮观后感
2015/06/18 职场文书
求职信:会计求职的写作技巧
2019/04/24 职场文书
Pytorch 使用tensor特定条件判断索引
2021/04/08 Python
在JavaScript中如何使用宏详解
2021/05/06 Javascript