You need to enable JavaScript to run this app. 使用FPDF循环生成订单PDF时每次迭代多出页面的解决方法
优惠活动
大模型
产品
解决方案
定价
更多

使用FPDF循环生成订单PDF时每次迭代多出页面的解决方法

页面累加问题的解决方法

异常根因

你全局初始化的FPDF实例是带持久内部状态的——调用output()导出文件的操作,只会把当前缓存的内容写入磁盘,不会自动清空实例里已经存好的页面内容:

  • 第一次生成10号订单时,实例里存了1页内容,导出10.pdf完成后,这页内容依然完整留在实例的缓存里
  • 第二次生成11号订单时,你在同一个实例上又新增1页,此时实例里已经累计存储了2页内容,导出11.pdf时自然会把这2页全部写进文件
  • 后续循环每多跑一次,实例里就多攒1页,最终就出现了后续PDF页数逐次递增的现象。

可行修正方案

方案1:每次生成时创建独立的全新FPDF实例(强推荐)

把FPDF的实例化逻辑挪到generate_pdf函数内部,每次调用时都生成无任何历史残留的干净实例,从根源上避免状态污染:

from fpdf import FPDF

def generate_pdf(DokId):
    # 每次调用都初始化全新的PDF对象,无历史内容残留
    pdf = FPDF()
    pdf.add_page()
    header = "Order #{}".format(DokId)
    
    pdf.set_font('Arial', 'B', 20)
    w = pdf.get_string_width(header) + 6
    pdf.set_x((210 - w) / 2)
    pdf.cell(w, 9, header, 0, 0, 'C')
    pdf.line(20, 18, 210-20, 18)
    pdf.output('{}.pdf'.format(DokId), 'F')
    return None

这种写法让每个订单的PDF生成流程完全独立,互不干扰,也不需要依赖库的内部实现细节,是兼容性最好、最不容易踩坑的写法。

方案2:复用全局实例时手动清空历史缓存

如果因为特殊需求必须复用同一个全局FPDF实例,就需要在每次新增页面前,手动把上一次生成时累积的页面缓存全部清空:

from fpdf import FPDF

pdf = FPDF()

def generate_pdf(DokId):
    # 清空上一轮生成残留的所有页面内容
    pdf.pages = {}
    pdf.page_no = 0
    pdf.add_page()
    header = "Order #{}".format(DokId)
    
    pdf.set_font('Arial', 'B', 20)
    w = pdf.get_string_width(header) + 6
    pdf.set_x((210 - w) / 2)
    pdf.cell(w, 9, header, 0, 0, 'C')
    pdf.line(20, 18, 210-20, 18)
    pdf.output('{}.pdf'.format(DokId), 'F')
    return None

注意:这种写法直接操作了FPDF的内部存储字段,属于依赖实现细节的写法,库版本迭代后可能出现字段名变更的兼容问题,非必要不使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.29 04:15:01