使用JavaScript向表中添加500,000行而不会导致页面崩溃

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (11)

我有一个报告系统,用户单击报告,执行SQL并将结果显示在表格中。我遇到的问题是单个报告为报告带来了超过500,000行。系统需要一段时间才能通过AJAX调用检索数据,但是一旦完成浏览器“挂起”,同时将HTML添加到页面中。

我的问题是,是否有另一种方法可以将HTML添加到页面而不会导致浏览器挂起?

var HTMLPRE = '<p class="text-center"><b id="lblReportStatus">Producing report...</b><br><small>Average time: ' + parseFloat($('#hidReportID').attr('data-avg')).toFixed(2) + ' seconds</small>' +
    '<br><small>Current time: <span id="divCurrentTimeTaken">0</span></small></p>';
window.CurrentTimer = 0;
$('#reportresults').html(HTMLPRE);
// start the timer
window.ProducingReportTimer = window.setInterval(function() {
    window.CurrentTimer++;
    $('#divCurrentTimeTaken').html(window.CurrentTimer + ' seconds');
}, 1000);

$.post(window.routes['ReportWriter.ProduceReport'], FormData, function(resp, status) {
    if (status === 'success') {
        if (resp.code == '200') {
            $('#lblReportStatus').text('Generating report...<br>Please note your browser may become un-responsive.  Please wait for a few minutes if this happens.');
            ProduceReportTable(resp);
        }
    } else {
        alert("Unable to produce report.  Please contact support with the below information:\r\nStatus code" + status);
    }
}).fail(function(err, status) {
    alert("Unable to produce report.  Please contact support with the below information:\r\n" + err);
});
function ProduceReportTable(resp){
    var ReportHTML = '<div class="row"><div class="col-xs-12"><button class="btn btn-primary" id="btnExportExcel"><i class="fa fa-file-excel"> Excel</i></a></div>' +
        '</div><div class="col-xs-12"><div class="table-responsive" style="overflow-x: auto;">' +
        '<table class="table-hover table-striped table" id="tblReport">' +
        '<thead><tr>';
    // loop through the headers first
    $(resp.headers).each(function (idx, head) {
        ReportHTML += '<th>' + head + '</th>';
    });

    ReportHTML += '</tr></thead><tbody>';
    // loop through the data

    $(resp.rows).each(function (idx, row) {
        ReportHTML += '<tr>';
        $.each(row, function() {
            ReportHTML += '<td>' + (this instanceof Window ? '' : this) + '</td>';
        });
        ReportHTML += '</tr>';
    });
    ReportHTML += '</tbody></table></div></div>';
    $('#reportresults').html(ReportHTML);
    window.clearInterval(window.ProducingReportTimer);
    /*
    $('#tblReport').dataTable({
        deferRender:    true,
        /*scrollY:        200,*//*
        scrollCollapse: true,
        scroller:       true
    });*/

    // enable the excel button
    $('#btnExportExcel').on('click', function(e){
        e.preventDefault();
        let TableSource = document.getElementById('tblReport');
        var today = new Date();
        var dd = today.getDate();
        var mm = today.getMonth()+1; //January is 0!
        var yyyy = today.getFullYear();
        if(dd<10) {
            dd = '0'+dd
        }
        if(mm<10) {
            mm = '0'+mm
        }
        today = yyyy + '-' + mm + '/' + dd;
        GenerateXLSX(TableSource, true, resp.ReportName + '-' + today + ".xlsx")
    });
}

很抱歉,如果在其他地方已经回答了这个问题,我已经进行了搜索并且无法找到任何内容。

提问于
用户回答回答于

没有。评论已经揭示了很好的答案; 它的要点是,从用户点(没有人可以同时处理那么多数据)和从安全点开始,从性能点(没有任何东西可以正确地渲染那么多数据)返回那么多行是一个坏主意(你冒着对你的应用程序进行巨大的DoS攻击的风险)。我可以想象的唯一用例就是创建一个报告,在这种情况下,您应该导出Excel / PDF文档,而不是用HTML显示它。

您应该实现分页和过滤选项来解决您的问题。如果必须使用JavaScript,请在应用程序上使用jquery Datatables和正确的AJAX端点。

扫码关注云+社区

领取腾讯云代金券