具有多个 chart.js 图表的页面到 pdf [英] Page with multiple chart.js charts to pdf

查看:21
本文介绍了具有多个 chart.js 图表的页面到 pdf的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 chart.js 生成了一个包含多个图表的报告页面.我需要将此报告导出为 PDF.可以通过搜索获得许多解决方案,但我找不到具有多个画布元素的解决方案.

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.

唯一可用的解决方案似乎是遍历所有图像,并使用图像重新创建报告,然后将其下载为 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.

有没有更简单/更有效的方法来完成这个?

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>

推荐答案

老实说,似乎最简单的方法就是提供一个下载到 PDF"链接,该链接会弹出浏览器的打印页面并指示用户选择打印为 pdf".

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".

如果这种方法对您(或您的用户)不起作用,那么这里有一个粗略的方法.

If that approach doesn't work for you (or your users), then here is a rough way to do it.

基本上,我们创建一个新的 canvas 元素,它是您的报告页面的大小,并将现有 chart.js canvas 图表中的像素增量绘制到新的 <代码>画布.完成后,您可以使用 jsPDF 将新画布作为图像添加到 pdf 文档并下载文件.

Basically, we create a new canvas element that is the size of your report page and incrementally paint the pixels from your existing chart.js canvas charts into the new canvas. Once that is done, then you can use jsPDF to add the new canvas to a pdf document as an image and download the file.

这是一个实现这一点的示例.

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');
});

您可以在此 codepen 中看到它的实际效果.

You can see it in action at this codepen.

现在让我们谈谈这种方法的一些问题.首先,您必须控制每个 chart.js canvas 在新 canvas 对象中的位置.做到这一点的唯一方法是了解报告页面的结构并实施相同的结构.在我的示例中,我的图表位于 2x2 网格中,逻辑会相应地处理此问题.如果您有一个 3x2 网格或其他东西,那么您将不得不更改定位逻辑.

Now let's talk about some gotchas with this approach. First, you have to control the position of each chart.js canvas in the new canvas object. 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.

最后,最终的 pdf 输出文件尺寸比原始图表页面(来自网络)大得多.我认为原因是因为我的图表容器"div 横跨整个页面.因此,您可能希望使用不同的方法来设置新 canvas 的大小.

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.

长话短说,上面的示例旨在展示一种方法,而不是您的最终解决方案.

So long story short, the above example is meant to demonstrate an approach and not be your final solution.

祝你好运!

这篇关于具有多个 chart.js 图表的页面到 pdf的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆