使用多个谷歌图表和jspdf生成PDF

时间:2016-10-06 09:08:55

标签: javascript pdf promise google-visualization jspdf

添加到此stackoverflow问题:Generating pdf using multiple graphs using html2canvas and jspdf

我尝试使用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');
    });

}

}

我正在做的是发送33个代表谷歌图表面板的divnames作为jspdf的参数来生成pdf。

问题:但是,单击“生成pdf”按钮时,Chrome浏览器会崩溃。调试后,它似乎正在传递for循环。但它永远不会进入Promise.all功能。

另外,最好指出以下内容:

  1. 例如,当我传递4个div时,pdf会成功生成。所以这是一个chrome没有处理生成的基础64s的问题?
  2. 我使用了&#39; FAST&#39;将图像添加到pdf时的参数,以使其压缩。
  3. 对此有何反馈?我做错了吗?

1 个答案:

答案 0 :(得分:1)

似乎代码有效,但扩展得不太好。

有可能通过并行执行所有操作,javascript的垃圾收集(GC)没有机会清除中间对象,而超大堆导致崩溃。

执行系列操作可能会产生积极影响。代码只是从问题中的代码派生而来。

首先,适配器功能,它宣传html2canvas()

function html2canvasAsync(element) {
    return new Promise(function(resolve, reject) {
        html2canvas(element, {
            onrendered: function (canvas) {
                resolve(canvas.toDataURL('image/png'));
            }
        });
    });
};

现在调用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');
        });
    }
}

仅检查语法

正如我所说,这将解决问题并不比“可能”更好。试一试不会花费任何费用。最糟糕的可能是Chrome崩溃。