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

PDFKit生成PDF发票分页异常问题求助

解决pdfkit分页时每页仅显示单个元素的问题

看起来你遇到的问题是因为pdfkit不会自动处理分页后的坐标重置,咱们来一步步拆解解决:

问题根源

你现在的代码只是持续累加itemPositionY来绘制每一行产品,但当这个Y坐标超过当前页面的可打印高度时,pdfkit会自动创建新页面,但新的内容依然会按照原来的Y坐标继续绘制——这就导致只有刚好跨过页边的那一行会出现在新页面上,剩下的内容都跑到页面之外了,看起来每页只显示一个元素。

修复方案

我们需要手动添加分页判断逻辑:在绘制每一行之前,检查当前位置加上行高是否会超出页面的可打印区域,如果会,就新增页面并把Y坐标重置到新页面的起始位置。

首先定义几个页面布局的常量(根据你的实际发票布局调整):

// A4页面默认高度是792,这里设置上下边距为40
const PAGE_MARGIN_TOP = 40;
const PAGE_MARGIN_BOTTOM = 40;
const PAGE_HEIGHT = 792;
// 可打印区域的底部Y坐标
const PRINTABLE_BOTTOM = PAGE_HEIGHT - PAGE_MARGIN_BOTTOM;
// 每行产品+底部水平线的总高度(你的行高20 + 水平线偏移15)
const ITEM_TOTAL_HEIGHT = 35;

然后修改你的循环代码,加入分页检查:

for (let i = 0; i < data.items.length; i++) { 
  const item = data.items[i]; 

  // 关键:检查当前位置是否会超出页面底部,需要分页
  if (this.itemPositionY + ITEM_TOTAL_HEIGHT > PRINTABLE_BOTTOM) {
    doc.addPage();
    // 重置Y坐标到新页面的产品起始位置(和第一页的初始值保持一致)
    this.itemPositionY = PAGE_MARGIN_TOP + 60; // 这里的60替换成你第一页开始画产品的初始Y值
  }

  if (item.bio) this.containBioProduct = true; 
  let itemName = item.bio ? `${item.item}*` : item.item; 
  this.generateTableRow( 
    doc, this.itemPositionY, itemName, "", 
    this.formatCurrency(item.itemPriceDf.toFixed(2)), 
    item.quantity, 
    this.formatCurrency(item.itemPriceTotalDf.toFixed(2)) 
  ); 
  this.generateHr(doc, this.itemPositionY + 15); 

  this.itemPositionY = this.itemPositionY + 20; 
}

额外注意点

  • 一定要根据你自己的发票布局调整PAGE_MARGIN_TOP、PAGE_MARGIN_BOTTOM和重置Y坐标时的数值,确保和第一页的产品起始位置匹配
  • 检查你的generateTableRow和generateHr函数,确认它们没有偷偷修改itemPositionY,否则会导致分页判断的计算错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:42:42