如何减少html-pdf生成报告所花费的时间?

时间:2019-06-08 07:24:52

标签: node.js phantomjs html-pdf phantomjs-node

我正在处理大量数据。我想生成一个包含1年数据的PDF报告。我正在使用html-pdf来做到这一点。问题是生成PDF大约需要20分钟。我可以减少吗?

我不想让我的用户等待20分钟。

注意:我只想在服务器端生成PDF,并希望将其邮寄给用户。

我尝试了一些解决方案,但是我什么都没有。但是我观察到的是,当我从Google下载某些文件时,工作流程非常顺利。

我想知道如何使我的工作流程顺畅

 app.post('/api', (req, res) => {
    var json = req.body;
    var sqlGet = 'SELECT StationId,TimeStamp,data->>"$.temperature" as temperature,data->"$.humidity" as humidity,data->"$.so2" as so2,data->"$.no2" as no2,data->"$.co" as co,data->"$.o3" as o3,data->"$.co2" as co2,data->"$.pm10" as pm10,data->"$.noise" as noise,data->"$.rain" as rain,data->"$.wdir" as wdir,data->"$.wspeed" as wspeed,data->"$.press" as press FROM TwentyStationFiveYearData WHERE StationId = ' + json.stationid + ' AND TimeStamp >= ' + json.start + ' AND TimeStamp <= ' + json.end;
    console.log('' + sqlGet);
    connection.query(sqlGet, function(err, result) {
        if (err) {
            console.log('error' + err);
        } else {
            var htmlCode = generateTable(result, 15);
            //var output = fs.createWriteStream('reports/' + json.start + '-' + json.end + '.pdf');
            pdf.create(htmlCode, {
                orientation: 'landscape',
                type: 'pdf',
                timeout: '1800000'
            }).toStream(function(err, stream) {
                if (err) {
                    console.log('stream did not work ' + err);
                } else {
                    stream.pipe(fs.createWriteStream('output.pdf'));
                    console.log('pdf generated');
                    res.send("report will be mailed");
                }
            });
        }
    });
});

function generateTable(jsonData, columns) {
    var tab = '';
    var headers = ['StationId', 'TimeStamp', 'temperature', 'humidity', 'so2', 'no2', 'co', 'o3', 'co2', 'pm10', 'noise', 'rain', 'wdir', 'wspeed', 'press'];
    tab += '<tr>';

    for (var c = 0; c < columns; c++) {
        tab += '<th>';
        tab += headers[c];
        tab += '</th>';
    }
    tab += '<tr>';
    jsonData.forEach(obj => {
        tab += '<tr>';
        for (var c = 0; c < columns; c++) {
            tab += '<td>';
            tab += obj[headers[c]];
            tab += '</td>';
        }
        tab += '</tr>';
    });
    tab = '<table border = "1">' + tab + '</table>';
    return html(tab);
}

function html(table) {
    var htmlCode = '<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><title>Title</title></head><body>' + table + '</body></html>';
    return htmlCode;

}

我想使我的工作流程更流畅,并减少生成PDF报告的时间

2 个答案:

答案 0 :(得分:0)

您是否缩小了耗时的操作范围? pdf渲染最耗时吗?

我要做的是检查原始查询以查看执行多少时间。

第二,我将检查结果的大小,如果可以某种方式压缩它,最后,我将检查PDF渲染。

我已经将dompdf用于PHP,并且在渲染png而不是jpg时出现性能问题,但是我认为情况并非如此,因为我看不到任何图像渲染。

因此,如果可以灵活地使用其他库,则最好这样做,否则请检查所用库中的性能调优。

我想字体渲染会花费很多时间。

希望我给你一些提示!

答案 1 :(得分:0)

https://itcodehub.blogspot.com/2019/06/using-optional-type-in-java.html使用npm's html-pdf。使用它时,它将在子流程中创建一个无显示的Web浏览器实例,然后使用它呈现您提供的html数据,然后使用同一实例将其打印到pdf文件。这样可行。但是,正如您所发现的那样,当给它一个大的html对象时,它的速度很慢。

仍然,20分钟是很长的时间。您的计算机是否可能受RAM限制? phantomjs子进程是否用完RAM并发生故障?

也许phantomjs更快。值得一试,而且比依靠pdf-puppeteer更具前瞻性。

您可以尝试now-deprecated phantomjs。它直接从您的节点程序内部生成pdf文件。 这样会更快,因为它不需要子进程。但是,您必须重新编写报告程序,使其使用PDFKit的API而不是浏览器实例。

有多种可用的软件即服务解决方案,其工作方式类似于html-pdf,但速度更快。您可能会考虑使用其中一种,尤其是在快速交付pdf文件对您的业务至关重要的情况下。

最后,即使您不想这样做,也可以编写HTML和CSS,这样可以很好地完成打印格式。并要求您的用户进行打印。