Javascript 带有多个 chart.js 图表的页面到 pdf
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43140467/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Page with multiple chart.js charts to pdf
提问by Sainath Krishnan
I have used chart.js to generate a report page that has multiple charts. I need to export this report to PDF. There are many solutions available via search, but I cannot find one which has multiple canvas elements.
我使用 chart.js 生成了一个包含多个图表的报告页面。我需要将此报告导出为 PDF。通过搜索有很多解决方案可用,但我找不到具有多个画布元素的解决方案。
The only available solution seems to be to loop through all the images, and recreate the report using the images, and then download that as a pdf.
唯一可用的解决方案似乎是遍历所有图像,并使用图像重新创建报告,然后将其下载为 pdf。
Is there any simpler/more efficient way to accomplish this?
有没有更简单/更有效的方法来实现这一点?
<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>
回答by jordanwillis
Honestly, it seems like the easiest approach would be to just provide a "download to PDF" link that pops up the browser's print page and instruct to user to select "print as pdf".
老实说,似乎最简单的方法是提供一个“下载到 PDF”链接,该链接会弹出浏览器的打印页面并指示用户选择“打印为 pdf”。
If that approach doesn't work for you (or your users), then here is a rough way to do it.
如果这种方法对您(或您的用户)不起作用,那么这里有一个粗略的方法。
Basically, we create a new canvaselement that is the size of your report page and incrementally paint the pixels from your existing chart.js canvascharts into the new canvas. Once that is done, then you can use jsPDFto add the new canvas to a pdf document as an image and download the file.
基本上,我们创建一个canvas与您的报告页面大小相同的新元素,并将现有 chart.jscanvas图表中的像素逐渐绘制到新的canvas. 完成后,您可以使用jsPDF将新画布作为图像添加到 pdf 文档并下载文件。
Here is an example implementation that does just that.
这是一个可以做到这一点的示例实现。
$('#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');
});
You can see it in action at this codepen.
Now let's talk about some gotchas with this approach. First, you have to control the position of each chart.js canvasin the new canvasobject. The only way to do that is to have an understanding of how your report page is structured and implement that same structure. In my example, my charts are in a 2x2 grid and the logic handles this accordingly. If you had a 3x2 grid or something different then you would have to change the positioning logic.
现在让我们谈谈这种方法的一些问题。首先,您必须控制每个 chart.jscanvas在新canvas对象中的位置。做到这一点的唯一方法是了解您的报告页面的结构并实施相同的结构。在我的示例中,我的图表位于 2x2 网格中,逻辑会相应地处理此问题。如果你有一个 3x2 的网格或不同的东西,那么你将不得不改变定位逻辑。
Lastly, the final pdf output file dimensions are much larger than the original chart page (from the web). I think the reason is because my chart "container" div stretches across the full page. Therefore, you probably want to use a different approach for setting the size of your new canvas.
最后,最终的 pdf 输出文件尺寸比原始图表页面(来自网络)大得多。我认为原因是我的图表“容器”div 横跨整个页面。因此,您可能希望使用不同的方法来设置新的canvas.
So long story short, the above example is meant to demonstrate an approach and not be your final solution.
长话短说,上面的例子是为了演示一种方法,而不是你的最终解决方案。
Good luck!
祝你好运!

