我已经使用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>
我有一个香草javascript的工作解决方案(虽然我使用ts键入)和使用lib jsPdf,在那里你需要每个pdf页面的情节:
let index = 1;
// create new pdf object
// if don't choose compress as true you will end up with a large pdf file
let pdf = new jsPDF({
orientation: 'landscape',
unit: 'px',
format: 'a4',
compress: true,
})
// search for the html element(s) you need
const canvas = document.querySelectorAll("canvas");
// here my size are in pixels since I configured that in the obj instance
let pageWidth = 400;
let pageHeight = 400;
let index = 1;
// traverse the array of canvas
canvas.forEach( (canva:HTMLCanvasElement) => {
// I added some options among others I added the type of the compression
// method: FAST
pdf.addImage(canva, 'PNG', 10, 10, pageWidth, pageHeight, `img${index}`, "FAST");
// so as to not end up with an extra pdf page at the end of the iteration
if (index < canvas.length) {
pdf.addPage();
}
index++;
});
// download the pdf
pdf.save('Reporte.pdf');
老实说,似乎最简单的方法是提供一个“下载到PDF”的链接,弹出浏览器的打印页面,并指示用户选择“打印为PDF”。
如果这种方法对你(或你的用户)不起作用,那么这里有一个粗略的方法。
基本上,我们创建一个新的canvas
元素,该元素的大小与您的报告页面相同,并将现有chart.jscanvas
图表中的像素增量绘制到新的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');
});
您可以在这个代码笔中看到它的作用。
现在,让我们谈谈这种方法的一些缺陷。首先,您必须控制每个chart.jscanvas
在新的canvas
对象中的位置。要做到这一点,唯一的方法是了解报表页面的结构并实现相同的结构。在我的示例中,我的图表位于2x2网格中,逻辑会相应地处理这个问题。如果您有一个3x2网格或其他不同的东西,那么您必须更改定位逻辑。
最后,最终的pdf输出文件尺寸比原始图表页面(来自web)大得多。我认为原因在于我的图表“容器”div贯穿了整个页面。因此,您可能希望使用不同的方法来设置新的画布的大小。
长话短说,上述示例旨在演示一种方法,而不是最终解决方案。
祝你好运!
我有一个docx4j生成的文件,其中包含几个表格、标题,最后还有一个excel生成的曲线图。 我尝试了许多方法,以将此文件转换为PDF,但没有得到任何成功的结果。 带有xsl fo的Docx4j不起作用,docx文件中包含的大部分内容尚未实现,并以红色文本显示为“未实现” 我在Apache POI中使用的代码如下: 我不知道该怎么做才能得到PDF中的图表,有人能告诉我如何继续吗? 提前感谢。
我正在使用,我已经能够获得一个html页面并为该页面生成pdf,但我需要从多个html页面生成一个pdf文档,并用页面分隔。例如:我有,。我需要一份3页的pdf文档,第一页的内容为之类的。。。 这是我的代码,它适用于一个html页面: 是否可以针对多个html页面进行循环,为每个html页面向PdfDocument添加一个新页面,然后仅生成一个pdf,每个html页面生成一个页面? 更新 我一直在
我有一个超文本标记语言的非常简单的表格,其中包含12列。我试图使用iText 5.1.1(Java)将其转换为PDF。 我的问题是,PDF输出中的表格换行了。我的意思是,它显示第一行,但在页面的末尾换行,然后没有换行符或任何东西,它只显示紧接在前一行的最后一个单元格之后的下一行。 如何使iText的HtmlWorker “nowrap”我的表格,即在PDF中显示一行? 顺便说一句,我仍然希望单元格
我想使用FlyingSaucer将一个包含阿拉伯字符的HTML页面转换为PDF文件,但生成的PDF不包含组合字符,并向后打印输出。 HTML: null null Java摘录: 我怎样做才能得到正确的结果?
我用 1 个类的不同数据填充我的表视图没有问题。但是它对多个类的我不起作用。知道如何解决这个问题吗?我已经在stackoverflow上查看了类似的问题。但他们都帮不了我。如果您对“回调”类有任何建议,请为我提供完整的导入,因为那里有几个回调类。 进一步的问题:如何在表格单元格的哈希集中显示实例的某个属性。所以我在我的 TaskControl 类中有一个 HashSet。在该HashSet中,有类