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

如何使用jsPDF-Autotable在同一文档中打印图表、图片或自定义HTML与表格?

解决jsPDF-Autotable动态组合图片/HTML与表格的问题

你的问题太常见了——硬编码margin的方式在元素尺寸不确定时完全行不通。其实我们可以利用jsPDF内置的位置追踪能力,搭配autotable的灵活配置,让表格自动“跟随”在任意元素下方,完全不用手动算尺寸。

场景1:动态定位图片下方的表格

你之前手动设置marginsParent.top = 105的方式,本质是依赖已知图片高度。改成下面的写法后,不管图片多大,表格都会自动贴在图片下方:

async printThisThingsTogether() { 
  const doc = new jsPDF('p', 'mm','a4'); 
  // 先处理图片,不提前硬编码表格margin
  const coolCanvas = document.getElementById('coolCanvas')! as HTMLCanvasElement; 
  const newCanvasImg = coolCanvas.toDataURL("image/png", 1.0)!;
  
  // 定义图片的基础位置和宽度,高度按比例自动计算(更灵活)
  const imgX = 10;
  const imgY = 10;
  const imgWidth = 190;
  // 等待图片加载完成,获取原始尺寸计算PDF中的显示高度
  const img = new Image();
  img.src = newCanvasImg;
  await new Promise(resolve => img.onload = resolve);
  const imgHeight = (img.height * imgWidth) / img.width;
  
  // 将图片添加到PDF
  doc.addImage(newCanvasImg, 'PNG', imgX, imgY, imgWidth, imgHeight); 
  
  // 关键:获取当前PDF内容的底部位置,加一点间距作为表格的top margin
  const tableTopMargin = doc.getY() + 5; // 5mm的留白间距
  const marginsParent = { 
    top: tableTopMargin, 
    bottom: 35, 
    left: 15, 
    right: 15 
  }; 

  doc.setFontSize(5); 
  doc.setPage(1); 

  let page = document.getElementById(`table`) as HTMLTableElement; 
  autoTable(doc, { 
    html: page, 
    margin: marginsParent, 
    useCss: false, 
    theme: 'plain', 
    styles: { 
      lineColor: [44, 62, 80], 
      lineWidth: 1, 
    }, 
    headStyles: { 
      fillColor: [241, 196, 15], 
      fontSize: 15, 
    }, 
    footStyles: { 
      fillColor: [241, 196, 15], 
      fontSize: 15, 
    }, 
    bodyStyles: { 
      fillColor: [52, 73, 94], 
      textColor: 240, 
    }, 
    alternateRowStyles: { 
      fillColor: [74, 96, 117], 
    }, 
  }); 

  await doc.output('dataurlnewwindow', {filename: 'listagem.pdf'}); 
}

核心逻辑:

  • 等待图片加载完成再计算尺寸,避免因异步加载导致的尺寸错误
  • 用doc.getY()获取当前PDF内容的底部坐标,动态设置表格的margin.top,彻底摆脱硬编码

场景2:自定义HTML文本 + 下方的小型表格

如果要渲染用户自定义的HTML(比如标题、说明文本),可以用jsPDF的html()方法先渲染HTML,再用同样的方式定位表格:

async printThisThingsTogether() { 
  const doc = new jsPDF('p', 'mm','a4'); 
  const customHtml = document.getElementById('user-custom-html')!;

  // 先把自定义HTML渲染到PDF
  await doc.html(customHtml, {
    x: 15,
    y: 10,
    width: 180, // 适配A4宽度(减去左右各15mm的边距)
  });

  // 依然用当前y位置定位表格,加5mm留白
  const tableTopMargin = doc.getY() + 5;
  const marginsParent = { 
    top: tableTopMargin, 
    bottom: 35, 
    left: 15, 
    right: 15 
  }; 

  // 表格部分的代码和之前一致
  let page = document.getElementById(`table`) as HTMLTableElement; 
  autoTable(doc, { 
    html: page, 
    margin: marginsParent, 
    // 其他样式配置...
  }); 

  await doc.output('dataurlnewwindow', {filename: 'listagem.pdf'}); 
}

额外技巧:跨页元素重复

如果表格很长会跨页,需要每一页顶部都重复图片/HTML,可以用autotable的didDrawPage钩子实现:

autoTable(doc, {
  // 其他配置项...
  didDrawPage: function(data) {
    // 在每一页顶部重新添加图片
    doc.addImage(newCanvasImg, 'PNG', 10, 10, 190, imgHeight);
    // 动态调整当前页表格的顶部位置
    data.settings.margin.top = imgY + imgHeight + 5;
  }
});

这样不管表格分多少页,每一页的表格都会自动跟在图片下方。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 00:18:12