如何使用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
相关产品推荐
相关产品推荐

