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

如何使用JSPDF在单个PDF中为每个表格动态添加上方标题

嘿,我刚好之前折腾过jsPDF生成多表格带动态标题的需求,给你分享几个靠谱的解决方案!核心思路其实很简单:跟踪PDF当前的Y轴绘制位置,每次画完标题和表格后,更新这个位置,确保下一组标题和表格能衔接在正确的地方。

方案一:使用jspdf-autotable插件(最常用)

如果是用jspdf-autotable插件生成表格(大部分人都会选这个,比原生画表格省心太多),可以直接利用插件返回的finalY属性获取表格绘制结束的位置,完美实现动态定位。

下面是完整的示例代码:

// 初始化PDF实例
const doc = new jsPDF();
let currentY = 20; // 初始Y坐标,预留顶部边距
const titleFontSize = 14;
const sectionMargin = 10; // 标题与表格、表格与下一个标题的间距

// 模拟多表格数据,每个对象包含标题和表格内容
const tableGroups = [
  { 
    title: "用户基础信息表", 
    tableData: [["ID", "姓名", "部门"], ["001", "张三", "技术部"], ["002", "李四", "市场部"]] 
  },
  { 
    title: "季度订单统计表", 
    tableData: [["订单号", "商品名称", "金额"], ["OD202401", "笔记本电脑", "5999"], ["OD202402", "无线鼠标", "99"], ["OD202403", "机械键盘", "299"]] 
  },
  // 可继续添加更多表格组
];

tableGroups.forEach(group => {
  // 1. 绘制当前表格的标题
  doc.setFontSize(titleFontSize);
  doc.setFont("helvetica", "bold"); // 标题设为加粗
  doc.text(group.title, 14, currentY); // 14是左侧边距

  // 计算标题实际高度,更新currentY(加5是标题到表格的小间距)
  const titleHeight = doc.getTextDimensions(group.title).h + 5;
  currentY += titleHeight;

  // 2. 绘制表格,指定起始Y坐标为currentY
  const tableResult = doc.autoTable({
    startY: currentY,
    head: [group.tableData[0]], // 表格表头
    body: group.tableData.slice(1), // 表格内容行
    theme: "striped", // 可选表格主题
    margin: { left: 14 } // 表格左侧边距和标题对齐
  });

  // 3. 更新currentY为表格结束后的位置,加上sectionMargin预留间距
  currentY = tableResult.finalY + sectionMargin;

  // 处理分页:如果当前位置超过页面底部,自动新增页面并重置currentY
  const pageBottomMargin = 20; // 底部预留边距
  if (currentY > doc.internal.pageSize.height - pageBottomMargin) {
    doc.addPage();
    currentY = 20; // 新页面的初始Y坐标
  }
});

// 导出PDF
doc.save("多表格带标题文档.pdf");

关键细节:

  • tableResult.finalY:插件返回的表格绘制完成后的最终Y坐标,是实现动态定位的核心
  • doc.getTextDimensions():精确计算标题文本的高度,比手动预估更准确
  • 分页判断:避免标题或表格被截断在页面底部

方案二:原生jsPDF绘制表格(无插件)

如果没用autotable,纯原生绘制表格,需要自己计算表格总高度,再更新currentY:

const doc = new jsPDF();
let currentY = 20;
const rowHeight = 10; // 每行表格的高度
const titleFontSize = 14;
const sectionMargin = 10;

const tableGroups = [/* 同方案一的表格数据 */];

tableGroups.forEach(group => {
  // 绘制标题
  doc.setFontSize(titleFontSize);
  doc.text(group.title, 14, currentY);
  currentY += doc.getTextDimensions(group.title).h + 5;

  // 原生绘制表格:先画表头,再画内容行
  const head = group.tableData[0];
  const body = group.tableData.slice(1);
  let x = 14;
  const colWidths = [30, 50, 40]; // 手动设置每列宽度

  // 画表头
  doc.setFont("helvetica", "bold");
  head.forEach((text, idx) => {
    doc.text(text, x, currentY);
    doc.rect(x, currentY - 2, colWidths[idx], rowHeight); // 画单元格边框
    x += colWidths[idx];
  });
  currentY += rowHeight;

  // 画内容行
  doc.setFont("helvetica", "normal");
  body.forEach(row => {
    x = 14;
    row.forEach((text, idx) => {
      doc.text(text, x, currentY);
      doc.rect(x, currentY - 2, colWidths[idx], rowHeight);
      x += colWidths[idx];
    });
    currentY += rowHeight;
  });

  // 更新currentY,加上间距
  currentY += sectionMargin;

  // 分页处理(同方案一)
  if (currentY > doc.internal.pageSize.height - 20) {
    doc.addPage();
    currentY = 20;
  }
});

doc.save("原生多表格带标题.pdf");

额外优化:表格跨页时重复标题

如果表格内容很长会跨页,可以在autotable的didDrawPage回调里,让每页顶部自动重复表格标题:

doc.autoTable({
  // ...其他参数
  didDrawPage: function(data) {
    // 在每页顶部绘制当前表格的标题
    doc.setFontSize(titleFontSize);
    doc.setFont("helvetica", "bold");
    doc.text(group.title, 14, 20);
  },
  // 让表格内容从标题下方开始绘制
  margin: { top: 30 }
});

这样不管表格跨多少页,每页顶部都会有对应的标题,阅读体验更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:13:55