我使用 chart.js 生成了一个包含多个图表的报告页面。我需要将此报告导出为 PDF。通过搜索可以找到许多解决方案,但我找不到具有多个 Canvas 元素的解决方案。
唯一可用的解决方案似乎是遍历所有图像,并使用图像重新创建报告,然后将其下载为 pdf 格式。
有没有更简单/更有效的方法来完成这个?
<body>
<h1> Chart 1 </h1>
<div style="width:800px; height:400px;">
<canvas id="chart_1" width="50" height="50"></canvas>
</div>
<h1> Chart 2 </h1>
<div style="width:800px; height:400px;">
<canvas id="chart_2" width="50" height="50"></canvas>
</div>
<h1> Chart 3 </h1>
<div style="width:800px; height:400px;">
<canvas id="chart_3" width="50" height="50"></canvas>
</div>
</body>
最佳答案
老实说,最简单的方法似乎是只提供一个“下载到 PDF”链接,该链接会弹出浏览器的打印页面并指示用户选择“打印为 pdf”。
如果该方法对您(或您的用户)不起作用,那么这里有一个粗略的方法。
基本上,我们创建一个新的 canvas
元素,它是您的报告页面的大小,并逐渐将现有 chart.js canvas
图表中的像素绘制到新的 Canvas
。完成后,您可以使用 jsPDF
将新 Canvas 作为图像添加到 pdf 文档并下载文件。
这是一个执行此操作的示例实现。
$('#downloadPdf').click(function(event) {
// get size of report page
var reportPageHeight = $('#reportPage').innerHeight();
var reportPageWidth = $('#reportPage').innerWidth();
// create a new canvas object that we will populate with all other canvas objects
var pdfCanvas = $('<canvas />').attr({
id: "canvaspdf",
width: reportPageWidth,
height: reportPageHeight
});
// keep track canvas position
var pdfctx = $(pdfCanvas)[0].getContext('2d');
var pdfctxX = 0;
var pdfctxY = 0;
var buffer = 100;
// for each chart.js chart
$("canvas").each(function(index) {
// get the chart height/width
var canvasHeight = $(this).innerHeight();
var canvasWidth = $(this).innerWidth();
// draw the chart into the new canvas
pdfctx.drawImage($(this)[0], pdfctxX, pdfctxY, canvasWidth, canvasHeight);
pdfctxX += canvasWidth + buffer;
// our report page is in a grid pattern so replicate that in the new canvas
if (index % 2 === 1) {
pdfctxX = 0;
pdfctxY += canvasHeight + buffer;
}
});
// create new pdf and add our new canvas as an image
var pdf = new jsPDF('l', 'pt', [reportPageWidth, reportPageHeight]);
pdf.addImage($(pdfCanvas)[0], 'PNG', 0, 0);
// download the pdf
pdf.save('filename.pdf');
});
您可以在这个 codepen 看到它的实际效果.
现在我们来谈谈这种方法的一些陷阱。首先,您必须控制每个 chart.js canvas
在新的 canvas
对象中的位置。做到这一点的唯一方法是了解您的报告页面的结构并实现相同的结构。在我的示例中,我的图表位于 2x2 网格中,逻辑会相应地处理它。如果您有 3x2 网格或其他不同的东西,那么您将不得不更改定位逻辑。
最后,最终的 pdf 输出文件尺寸比原始图表页面(来自网络)大得多。我认为原因是因为我的图表“容器”div 横跨整个页面。因此,您可能希望使用不同的方法来设置新 canvas
的大小。
长话短说,上面的示例旨在演示一种方法,而不是您的最终解决方案。
祝你好运!
关于javascript - 包含多个 chart.js 图表到 pdf 的页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43140467/