1

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

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

注意:我只想在服务器端生成 PDF,我想把它邮寄给用户。

我尝试了一些解决方案,但我不喜欢任何解决方案。但我观察到的是,当我从谷歌下载一些文件时,工作流程非常流畅。

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

 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 报告所需的时间

4

2 回答 2

0

npm 的html-pdf用途phantomjs。当您使用它时,它会在子进程中创建一个无显示的 Web 浏览器实例,然后使用它来呈现您提供给它的 html 数据,然后使用相同的实例将其打印到 pdf 文件中。这样可行。但是正如你所发现的,当你给它一个大的 html 对象时它会很慢。

尽管如此,20分钟还是很长的时间。您的机器是否可能受到 RAM 限制?phantomjs 子进程是否耗尽 RAM 并抖动?

也许pdf-puppeteer更快。值得一试,而且它比依赖现已弃用的 phantomjs 更具前瞻性

你可以试试PDFKit。它直接从您的节点程序中生成 pdf 文件。这会更快,因为它不需要子进程。但是,您必须重新编写报表程序,以便它使用 PDFKit 的 API 而不是浏览器实例。

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

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

于 2019-06-08T15:00:00.703 回答
0

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

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

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

我在 PHP 中使用了 dompdf,当我渲染 png 而不是 jpg 时出现了性能问题,但我认为情况并非如此,因为我没有看到任何图像渲染。

因此,如果灵活地使用另一个库,您最好这样做,否则检查您使用的库的性能调整。

我想字体渲染可能需要很多时间。

希望我给了你一些提示!

于 2019-06-08T14:42:11.300 回答