Django生成PDF并解决中文乱码:基于xhtml2pdf的完整实现
本文介绍如何在Django项目中利用xhtml2pdf库生成PDF文件,重点解决中文显示乱码问题。通过配置中文字体、编写表单验证与类视图,实现用户信息到PDF的转换。文章包含完整的安装步骤、代码示例及字体配置方法,帮助开发者快速实现PDF下载与预览功能。
项目源码已托管于GitHub: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文件。用户可在网页中直接浏览、放大或缩小查看,亦支持下载,操作便捷。欢迎克隆代码进行实际测试。
项目源码地址:https://github.com/PythonerKK/django-generate-pdf/tree/master
以上内容为本文全部介绍,期望对读者的学习有所助益,同时也感谢大家的支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













