You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django项目:服务端将已渲染动态页面转PDF实现示例请求

在Django中将动态渲染页面转为PDF的服务端方案

刚好我在Django项目里处理过类似的需求——把服务端渲染的动态页面转成PDF,还得支持西里尔文,客户端方案确实踩过不少坑,给你分享几个靠谱的服务端实现方案:

方案一:WeasyPrint(推荐,纯Python,Unicode友好)

WeasyPrint是纯Python编写的PDF生成库,对现代CSS支持不错,原生支持Unicode(包括西里尔文),不需要额外安装二进制依赖,非常适合Django场景。

实现步骤:

  1. 安装依赖:
pip install weasyprint
  1. 编写Django视图函数:
    先通过render_to_string把动态数据渲染成HTML字符串,再用WeasyPrint转换成PDF返回给客户端:
from django.template.loader import render_to_string
from weasyprint import HTML
from django.http import HttpResponse

def dynamic_page_to_pdf(request):
    # 模拟你的动态数据(可以从数据库/API获取)
    context = {
        'page_title': '我的动态PDF页面',
        'welcome_text': 'Привет, мир!',  # 西里尔文字符
        'data_list': ['Первый элемент', 'Второй элемент', 'Третий элемент']
    }
    
    # 渲染模板为HTML字符串
    html_content = render_to_string('dynamic_pdf_template.html', context)
    
    # 生成PDF文件
    pdf_file = HTML(string=html_content).write_pdf()
    
    # 构造响应,让浏览器下载PDF
    response = HttpResponse(pdf_file, content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="dynamic_content.pdf"'
    return response
  1. 编写对应的模板(templates/dynamic_pdf_template.html):
    关键是要使用支持西里尔文的字体,避免乱码:
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>{{ page_title }}</title>
    <style>
        /* 使用支持西里尔文的字体,DejaVu Sans是免费且常用的选择 */
        body { font-family: 'DejaVu Sans', sans-serif; padding: 20px; }
        .list-container { margin-top: 20px; }
        .list-item { margin: 8px 0; list-style-type: square; }
    </style>
</head>
<body>
    <h1>{{ welcome_text }}</h1>
    <div class="list-container">
        <h3>动态数据列表:</h3>
        <ul>
            {% for item in data_list %}
                <li class="list-item">{{ item }}</li>
            {% endfor %}
        </ul>
    </div>
</body>
</html>

注意事项:

  • 如果服务器上没有DejaVu Sans字体,可以通过@font-face加载Web字体,或者在服务器上安装该字体
  • WeasyPrint支持大部分CSS3特性,复杂样式也能很好渲染

方案二:xhtml2pdf(轻量,适合简单页面)

xhtml2pdf是另一个常用的Django PDF生成库,体积更小,适合结构简单的页面,同样支持Unicode字符。

实现步骤:

  1. 安装依赖:
pip install xhtml2pdf
  1. 编写视图函数:
from django.template.loader import render_to_string
from xhtml2pdf import pisa
from django.http import HttpResponse

def generate_pdf(request):
    context = {
        'title': 'xhtml2pdf动态示例',
        'content': '西里尔文测试:Привет из xhtml2pdf!'
    }
    
    # 渲染HTML
    html_content = render_to_string('simple_pdf_template.html', context)
    
    # 构造响应
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="simple_output.pdf"'
    
    # 生成PDF,指定UTF-8编码
    pisa_status = pisa.CreatePDF(html_content, dest=response, encoding='UTF-8')
    
    # 处理生成错误
    if pisa_status.err:
        return HttpResponse(f'PDF生成失败: {pisa_status.err}')
    return response
  1. 模板中同样要指定支持西里尔文的字体,可以把字体文件放到静态目录,通过@font-face引入:
@font-face {
    font-family: 'DejaVuSans';
    src: url('{{ STATIC_URL }}fonts/DejaVuSans.ttf') format('truetype');
}
body { font-family: DejaVuSans, sans-serif; }

方案三:wkhtmltopdf(适合复杂HTML/CSS)

如果你的动态页面包含复杂的CSS布局甚至少量JavaScript,wkhtmltopdf会更合适——它基于WebKit引擎,相当于把页面在浏览器中渲染后转成PDF,对HTML/CSS的支持几乎完美。

实现步骤:

  1. 安装wkhtmltopdf二进制文件:
  • Ubuntu/Debian:sudo apt-get install wkhtmltopdf
  • Windows:从官方渠道下载安装包并配置环境变量
  1. 安装Django集成库:
pip install django-wkhtmltopdf
  1. 编写视图:
from django.views.generic import View
from wkhtmltopdf.views import PDFTemplateResponse

class DynamicPDFView(View):
    def get(self, request):
        context = {
            'dynamic_content': 'Привет, это由wkhtmltopdf生成的PDF!'
        }
        return PDFTemplateResponse(
            request=request,
            template='complex_pdf_template.html',
            filename='complex_dynamic.pdf',
            context=context,
            content_type='application/pdf'
        )

注意事项:

  • 需要确保服务器上安装了wkhtmltopdf二进制,并且Django能找到它的路径(可以在settings.py中配置WKHTMLTOPDF_CMD)
  • 对JavaScript渲染的内容支持也很好,如果你的页面有前端动态渲染的部分,这个方案更适合

总结

  • 如果追求纯Python、无额外依赖,优先选WeasyPrint,足够应对大部分动态页面,西里尔文支持完美
  • 页面结构简单、追求轻量,选xhtml2pdf
  • 复杂布局/需要JS支持,选wkhtmltopdf

所有方案都需要注意使用支持西里尔文的字体,确保模板编码为UTF-8,这样就能避免乱码问题了。

内容的提问来源于stack exchange,提问作者Aleks Porberevskiy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:46:45