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

Flask API中如何用pdfkit生成PDF流而非写入服务器文件?

Flask API 用pdfkit生成PDF并返回流的解决方案

一、直接返回PDF字节流(推荐)

pdfkit 支持直接返回PDF的字节数据,无需写入服务器文件。只需将from_file(或from_string)的第二个输出路径参数设为False,方法就会返回PDF的bytes对象,之后在Flask中直接返回该对象并设置正确的响应头即可。

示例代码:

from flask import Flask, make_response
import pdfkit

app = Flask(__name__)

# 配置pdfkit,指定wkhtmltopdf的路径(若环境变量未配置则必须指定)
config = pdfkit.configuration(wkhtmltopdf='/path/to/wkhtmltopdf')

@app.route('/generate-pdf')
def generate_pdf():
    # 读取HTML文件,也可直接传入HTML字符串用from_string方法
    html_path = 'input.html'
    # 生成PDF字节数据
    pdf_bytes = pdfkit.from_file(html_path, False, configuration=config)
    
    # 构造响应
    response = make_response(pdf_bytes)
    # 设置响应内容类型为PDF
    response.headers['Content-Type'] = 'application/pdf'
    # 控制浏览器行为:inline为在线预览,attachment为触发下载,可按需修改
    response.headers['Content-Disposition'] = 'attachment; filename="output.pdf"'
    
    return response

if __name__ == '__main__':
    app.run()

如果之前尝试该方法失败,大概率是wkhtmltopdf路径未正确配置,不同系统的默认路径参考:

  • Windows:C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe
  • Linux:/usr/bin/wkhtmltopdf
  • macOS:/usr/local/bin/wkhtmltopdf

二、临时文件方案(备选)

如果因特殊情况无法使用字节流返回,可以用临时文件方案,生成唯一命名的临时PDF,读取后立即删除,避免服务器存储占用。推荐使用Python标准库tempfile处理文件名唯一性和自动清理:

示例代码:

from flask import Flask, make_response
import pdfkit
import tempfile
import os

app = Flask(__name__)
config = pdfkit.configuration(wkhtmltopdf='/path/to/wkhtmltopdf')

@app.route('/generate-pdf')
def generate_pdf():
    html_path = 'input.html'
    
    # 创建临时PDF文件,delete=False表示先不自动删除,后续手动清理
    with tempfile.NamedTemporaryFile(suffix='.pdf', delete=False) as temp_file:
        temp_pdf_path = temp_file.name
    
    try:
        # 生成PDF到临时文件
        pdfkit.from_file(html_path, temp_pdf_path, configuration=config)
        
        # 读取临时文件内容
        with open(temp_pdf_path, 'rb') as f:
            pdf_bytes = f.read()
    finally:
        # 无论生成成功与否,都删除临时文件,避免残留
        os.unlink(temp_pdf_path)
    
    # 构造响应
    response = make_response(pdf_bytes)
    response.headers['Content-Type'] = 'application/pdf'
    response.headers['Content-Disposition'] = 'attachment; filename="output.pdf"'
    
    return response

if __name__ == '__main__':
    app.run()

该方案通过NamedTemporaryFile自动生成唯一文件名,避免多用户并发时的文件冲突,finally块确保临时文件一定会被清理,不会产生垃圾文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 14:41:33