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

Python/Django环境下使用xhtml2pdf生成内存PDF字节的实现问题

错误原因

你现有代码存在两个核心问题:

  1. 变量名错误:你定义的内存对象是output,但返回时调用了不存在的new_output变量
  2. 字节流指针位置错误:pisa.CreatePDF写入完成后,BytesIO的文件指针会停在内容末尾,直接调用read()会读到空内容,需要先将指针移动到流的起始位置

正确实现代码

from io import BytesIO
from xhtml2pdf import pisa

def html_to_pdf(html: str) -> bytes | None:
    """
    将HTML字符串转换为PDF字节数据,不写入磁盘
    """
    # 初始化内存字节流
    output = BytesIO()
    # 渲染PDF到内存流,显式指定编码避免中文乱码
    pisa_status = pisa.CreatePDF(
        src=html,
        dest=output,
        encoding='utf-8'
    )
    # 渲染出错时返回None,也可根据业务需求自定义抛出异常
    if pisa_status.err:
        return None
    # 将字节流指针移动到起始位置
    output.seek(0)
    # 读取全部PDF字节数据
    pdf_bytes = output.read()
    # 关闭流释放内存
    output.close()
    return pdf_bytes

Django场景补充说明

  • 如果需要在Django视图中直接返回PDF给前端,可以直接用生成的字节数据构造HttpResponse,示例:
from django.http import HttpResponse

def download_pdf_view(request):
    # 此处替换为你的业务HTML内容
    html_content = "<h1>测试PDF内容</h1>"
    pdf_bytes = html_to_pdf(html_content)
    if not pdf_bytes:
        return HttpResponse("PDF生成失败", status=500)
    response = HttpResponse(pdf_bytes, content_type='application/pdf')
    response['Content-Disposition'] = 'attachment; filename="output.pdf"'
    return response
  • Python 3场景下不要使用StringIO,StringIO处理的是字符串流,PDF属于二进制内容,必须使用BytesIO才能正常处理

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 10:21:02