Django生成PDF并解决中文乱码的完整教程

陈默
陈默
发布时间:2026-10-13 | 4人浏览过
原创

本文介绍如何使用Django结合xhtml2pdf库生成PDF文档,并重点解决中文显示乱码问题。通过配置msyh.ttf字体、编写表单验证与类视图,实现从用户输入到PDF下载的全流程。代码包含FormView构建、PDF响应生成及字体补丁函数的具体实现,帮助开发者快速掌握Django中PDF生成的核心技巧。

项目介绍与源码获取

项目源码已托管于:https://github.com/PythonerKK/django-generate-pdf/tree/master

该示例演示了如何根据用户提交的个人信息生成简历PDF,旨在说明利用Django的HttpResponse对象创建PDF文档的具体方法。

以下是最终效果的展示:

环境依赖安装

环境依赖安装

首先,请安装Django最新版本2.2.2以及用于处理PDF的依赖包xhtml2pdf。


pip install django
pip install xhtml2pdf

表单验证与视图开发

表单数据验证逻辑

为简化示例,本项目依赖数据库存储,仅需关注表单数据的验证过程。

文件路径: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格式的响应对象。

此处可借助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响应生成逻辑

生成PDF响应对象的处理

在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响应的逻辑之前执行。

遵循上述步骤即可成功生成PDF文件。用户可在网页中直接浏览、放大或缩小查看,亦支持下载操作,整个过程便捷且简单。

建议直接克隆代码仓库以测试实际效果。

以上关于Django生成PDF并在网页显示及解决中文乱码的方法即为全部分享内容,希望能提供有益参考,欢迎支持。

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表