作者:王家刚163034 | 来源:互联网 | 2023-02-07 21:06
我使用chart.js生成一个包含多个图表的报表页面.我需要将此报告导出为PDF.通过搜索有许多解决方案,但我找不到具有多个canvas元素的解决方案.
唯一可用的解决方案似乎是循环遍历所有图像,并使用图像重新创建报告,然后将其作为pdf下载.
有没有更简单/更有效的方法来实现这一目标?
Chart 1
Chart 2
Chart 3
jordanwillis..
16
老实说,似乎最简单的方法是提供一个"下载到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 = $('').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
新canvas
对象中每个chart.js的位置.唯一的方法是了解报表页面的结构并实现相同的结构.在我的例子中,我的图表是2x2网格,逻辑处理相应的.如果您有3x2网格或不同的网格,则必须更改定位逻辑.
最后,最终的pdf输出文件尺寸远大于原始图表页面(来自网络).我认为原因是因为我的图表"容器"div延伸到整个页面.因此,您可能希望使用不同的方法来设置新的大小canvas
.
长话短说,上面的例子是为了展示一种方法而不是你的最终解决方案.
祝好运!
1> jordanwillis..:
老实说,似乎最简单的方法是提供一个"下载到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 = $('').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
新canvas
对象中每个chart.js的位置.唯一的方法是了解报表页面的结构并实现相同的结构.在我的例子中,我的图表是2x2网格,逻辑处理相应的.如果您有3x2网格或不同的网格,则必须更改定位逻辑.
最后,最终的pdf输出文件尺寸远大于原始图表页面(来自网络).我认为原因是因为我的图表"容器"div延伸到整个页面.因此,您可能希望使用不同的方法来设置新的大小canvas
.
长话短说,上面的例子是为了展示一种方法而不是你的最终解决方案.
祝好运!