Chart.jsを使用して、複数のグラフを含むレポートページを生成しました。このレポートをPDFにエクスポートする必要があります。検索で利用できる解決策はたくさんありますが、複数のキャンバス要素を持つ解決策は見つかりません。
利用可能な唯一の解決策は、すべての画像をループして、画像を使用してレポートを再作成し、それを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
を使用して、新しいキャンバスを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 で実際の動作を確認できます。
ここで、このアプローチに関するいくつかの落とし穴について話しましょう。まず、新しいcanvas
オブジェクト内の各chart.js canvas
の位置を制御する必要があります。これを行う唯一の方法は、レポートページの構造を理解し、同じ構造を実装することです。私の例では、チャートは2x2グリッドにあり、ロジックはこれを適切に処理します。 3x2グリッドなどがある場合は、配置ロジックを変更する必要があります。
最後に、最終的なPDF出力ファイルのサイズは、(Webからの)元のチャートページよりもはるかに大きくなります。その理由は、チャートの「コンテナー」のdivがページ全体に広がっているためです。したがって、おそらく新しいcanvas
のサイズを設定するために別のアプローチを使用したいと思うでしょう。
要するに、上記の例はアプローチを示すことを目的としており、最終的なソリューションではありません。
幸運を!