[英]Generating PDF using multiple google charts and jspdf
Adding to this stackoverflow question: Generating pdf using multiple graphs using html2canvas and jspdf添加到这个 stackoverflow 问题: 使用 html2canvas 和 jspdf 使用多个图形生成 pdf
I have tried to use the Promise javascript api as follows:我尝试使用 Promise javascript api 如下:
function GeneratePDFforCharts(divNamesForPDF)
{
var arrayOfPromises = [];
//Note: Checking if the browser supports Promises
if (window.Promise) {
for (var i = 0; i < divNamesForPDF.length; i++)
{
var promise = new Promise(function (resolve, reject) {
//asynchronous code goes here
//Note: The Promise is passed a callback function. The callback takes two arguments, resolve and reject.
//Note: If everything is successful, the promise is fullfilled by calling resolve(). In case of an error, reject() is called with an Error object.
var element = $(divNamesForPDF[i]).get(0);
html2canvas(element, {
onrendered: function (canvas) {
resolve(canvas.toDataURL('image/png'));
}
});
});
arrayOfPromises.push(promise);
}
Promise.all(arrayOfPromises).then(function (canvases) {
var count = 0;
var pageNumber = 1;
var doc = new jsPDF('l', 'mm', [297, 210], true); //true is set for pdf compression
for (var i = 0; i < canvases.length; i++)
{
if (isOdd(count)) //2nd chart
{
doc.addImage(canvases[i], 'PNG', 10, 105, 270, 100, null, 'FAST'); //x, y, width, height - FAST is used for png compression
var pageNo = pageNumber.toString();
doc.text(140, 207, pageNo); //x, y, text
pageNumber++;
}
else //1st chart
{
if (count != 0)
{
doc.addPage();
}
doc.addImage(canvases[i], 'PNG', 10, 5, 270, 100, null, 'FAST');
}
count++;
}
doc.save('IEA_Global_MonthlyStocks_Analytics.pdf');
});
}
}
What I am doing is sending 33 divnames representing google chart panels as a parameter for the jspdf to generate the pdf.我正在做的是发送 33 个 divnames 代表谷歌图表面板作为 jspdf 生成 pdf 的参数。
Problem: However, the Chrome browser is crashing when clicking on the generate pdf button.问题:但是,Chrome 浏览器在单击生成 pdf 按钮时崩溃。 After debugging it seems that it is passing the for loop.
经过调试,它似乎正在传递 for 循环。 However it never goes in the Promise.all function.
但是它永远不会出现在 Promise.all 函数中。
Also, it is good to point out the following:此外,最好指出以下几点:
Any feedback on this?对此有任何反馈吗? Am I doing something wrong please?
请问我做错了吗?
It seems that the code works but doesn't scale too well.代码似乎有效,但扩展性不太好。
It's possible that by performing all operations in parallel, javascript's Garbage Collection (GC) isn't given the opportunity to clear intermediate objects, and an oversized heap causes the crash.有可能通过并行执行所有操作,javascript 的垃圾收集 (GC) 没有机会清除中间对象,并且过大的堆会导致崩溃。
Performing the operations in series may have a positive effect.依次执行这些操作可能会产生积极的影响。 The code is simply derived from the code in the question.
该代码只是从问题中的代码派生而来。
First, an adaptor function, which promisifies html2canvas()
:首先,一个适配器函数,它承诺
html2canvas()
:
function html2canvasAsync(element) {
return new Promise(function(resolve, reject) {
html2canvas(element, {
onrendered: function (canvas) {
resolve(canvas.toDataURL('image/png'));
}
});
});
};
Now call divNamesForPDF.reduce(...)
to serialize the asynchronous operations and progressively add to the jsPDF doc
:现在调用
divNamesForPDF.reduce(...)
来序列化异步操作并逐步添加到 jsPDF doc
:
function GeneratePDFforCharts(divNamesForPDF) {
if (window.Promise) {
var doc = new jsPDF('l', 'mm', [297, 210], true); //true is set for pdf compression
return divNamesForPDF.reduce(function(p, name, i) {
return p.then(function(pageNumber) {
return html2canvasAsync($(name).get(0)) // or `document.getElementById(name)` ?
// return html2canvasAsync(document.getElementById(name)) // possibly?
.then(function(canvas) {
if (isOdd(i)) { // odds
doc.addImage(canvas, 'PNG', 10, 105, 270, 100, null, 'FAST'); //x, y, width, height - FAST is used for png compression
doc.text(140, 207, pageNumber.toString()); //x, y, text
pageNumber++;
} else { // evens
if (i > 0) {
doc.addPage();
}
doc.addImage(canvas, 'PNG', 10, 5, 270, 100, null, 'FAST');
}
return pageNumber;
}).catch(function(e) {
// Error handling is a good idea
console.log(e);
doc.text(35, 25, e.message); // possibly add the error message to doc
});
});
}, Promise.resolve(1)) // starter promise resolved with page number 1
.then(function() {
doc.save('IEA_Global_MonthlyStocks_Analytics.pdf');
});
}
}
checked only for syntax只检查语法
As I say, it's no better than "possible" that this will fix the issue.正如我所说,这不会比“可能”更好地解决问题。 It won't cost anything to give it a try.
尝试它不会花费任何费用。 The worst that might happen is another Chrome crash.
可能发生的最糟糕的情况是另一次 Chrome 崩溃。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.