如何使用Ajax从Datatables导出所有行?

Fox*_*Fox 22 ajax asp.net-mvc jquery export datatables

我正在使用Datatables中的新功能:"HTML5导出按钮".我正在使用Ajax加载数据.

https://datatables.net/extensions/buttons/examples/html5/simple.html

问题是它只导出当前显示的页面.

我这样出口:

buttons: [
    {
        extend: 'pdfHtml5',
        text: 'PDF',
        exportOptions: {
            "columns": ':visible',
        }
    },
]
Run Code Online (Sandbox Code Playgroud)

如何导出所有行?

Cha*_*mar 39

非常感谢用户“kevinpo”。他给出了当服务器端处理为 On时如何将 jquery 数据表中的所有记录下载为 excel 的方法。根据他的回答,我在这里实现了用于服务器端处理的完整导出功能(复制、excel、csv、pdf、打印)。

在里面 $(document).ready()定义下面的函数并在action每个导出按钮上调用这个函数,如下所示:

/* For Export Buttons available inside jquery-datatable "server side processing" - Start
- due to "server side processing" jquery datatble doesn't support all data to be exported
- below function makes the datatable to export all records when "server side processing" is on */

function newexportaction(e, dt, button, config) {
    var self = this;
    var oldStart = dt.settings()[0]._iDisplayStart;
    dt.one('preXhr', function (e, s, data) {
        // Just this once, load all data from the server...
        data.start = 0;
        data.length = 2147483647;
        dt.one('preDraw', function (e, settings) {
            // Call the original action function
            if (button[0].className.indexOf('buttons-copy') >= 0) {
                $.fn.dataTable.ext.buttons.copyHtml5.action.call(self, e, dt, button, config);
            } else if (button[0].className.indexOf('buttons-excel') >= 0) {
                $.fn.dataTable.ext.buttons.excelHtml5.available(dt, config) ?
                    $.fn.dataTable.ext.buttons.excelHtml5.action.call(self, e, dt, button, config) :
                    $.fn.dataTable.ext.buttons.excelFlash.action.call(self, e, dt, button, config);
            } else if (button[0].className.indexOf('buttons-csv') >= 0) {
                $.fn.dataTable.ext.buttons.csvHtml5.available(dt, config) ?
                    $.fn.dataTable.ext.buttons.csvHtml5.action.call(self, e, dt, button, config) :
                    $.fn.dataTable.ext.buttons.csvFlash.action.call(self, e, dt, button, config);
            } else if (button[0].className.indexOf('buttons-pdf') >= 0) {
                $.fn.dataTable.ext.buttons.pdfHtml5.available(dt, config) ?
                    $.fn.dataTable.ext.buttons.pdfHtml5.action.call(self, e, dt, button, config) :
                    $.fn.dataTable.ext.buttons.pdfFlash.action.call(self, e, dt, button, config);
            } else if (button[0].className.indexOf('buttons-print') >= 0) {
                $.fn.dataTable.ext.buttons.print.action(e, dt, button, config);
            }
            dt.one('preXhr', function (e, s, data) {
                // DataTables thinks the first item displayed is index 0, but we're not drawing that.
                // Set the property to what it was before exporting.
                settings._iDisplayStart = oldStart;
                data.start = oldStart;
            });
            // Reload the grid with the original page. Otherwise, API functions like table.cell(this) don't work properly.
            setTimeout(dt.ajax.reload, 0);
            // Prevent rendering of the full data to the DOM
            return false;
        });
    });
    // Requery the server with the new one-time export settings
    dt.ajax.reload();
};
//For Export Buttons available inside jquery-datatable "server side processing" - End
Run Code Online (Sandbox Code Playgroud)

对于按钮,定义如下

"buttons": [{
               "extend": 'copy',
               "text": '<i class="fa fa-files-o" style="color: green;"></i>',
               "titleAttr": 'Copy',                               
               "action": newexportaction
            },
            {
               "extend": 'excel',
               "text": '<i class="fa fa-file-excel-o" style="color: green;"></i>',
               "titleAttr": 'Excel',                               
               "action": newexportaction
            },
            {
               "extend": 'csv',
               "text": '<i class="fa fa-file-text-o" style="color: green;"></i>',
               "titleAttr": 'CSV',                               
               "action": newexportaction
            },
            {
               "extend": 'pdf',
               "text": '<i class="fa fa-file-pdf-o" style="color: green;"></i>',
               "titleAttr": 'PDF',                               
               "action": newexportaction
            },
            {
               "extend": 'print',
               "text": '<i class="fa fa-print" style="color: green;"></i>',
               "titleAttr": 'Print',                                
               "action": newexportaction
            }],
Run Code Online (Sandbox Code Playgroud)

就是这样。现在您的下载已准备就绪。

  • 在其他高票答案失败后,对我来说非常有效......我真的需要在 js 方面做得更好 (3认同)
  • 就像魔术一样!多么神奇的功能...您值得拥有的不仅仅是一个喜欢! (3认同)
  • @Stoobish你不需要DataTable id,你可以使用`dt`,如`data.length = dt.page.info().recordsTotal;` (3认同)
  • 这个答案应该是得票最高的一个。这节省了我几个小时的工作时间。荣誉 (2认同)

kev*_*npo 26

您需要告诉AJAX函数获取所有数据,然后执行导出但取消实际绘制,以便所有数据都不会加载到DOM中.完整数据仍将存在于DataTables API的内存中,因此您需要将其刷新到导出之前的状态.

var oldExportAction = function (self, e, dt, button, config) {
    if (button[0].className.indexOf('buttons-excel') >= 0) {
        if ($.fn.dataTable.ext.buttons.excelHtml5.available(dt, config)) {
            $.fn.dataTable.ext.buttons.excelHtml5.action.call(self, e, dt, button, config);
        }
        else {
            $.fn.dataTable.ext.buttons.excelFlash.action.call(self, e, dt, button, config);
        }
    } else if (button[0].className.indexOf('buttons-print') >= 0) {
        $.fn.dataTable.ext.buttons.print.action(e, dt, button, config);
    }
};

var newExportAction = function (e, dt, button, config) {
    var self = this;
    var oldStart = dt.settings()[0]._iDisplayStart;

    dt.one('preXhr', function (e, s, data) {
        // Just this once, load all data from the server...
        data.start = 0;
        data.length = 2147483647;

        dt.one('preDraw', function (e, settings) {
            // Call the original action function 
            oldExportAction(self, e, dt, button, config);

            dt.one('preXhr', function (e, s, data) {
                // DataTables thinks the first item displayed is index 0, but we're not drawing that.
                // Set the property to what it was before exporting.
                settings._iDisplayStart = oldStart;
                data.start = oldStart;
            });

            // Reload the grid with the original page. Otherwise, API functions like table.cell(this) don't work properly.
            setTimeout(dt.ajax.reload, 0);

            // Prevent rendering of the full data to the DOM
            return false;
        });
    });

    // Requery the server with the new one-time export settings
    dt.ajax.reload();
};
Run Code Online (Sandbox Code Playgroud)

和:

    buttons: [
        {
            extend: 'excel',
            action: newExportAction
        },
Run Code Online (Sandbox Code Playgroud)

  • 当您要导出所有数据而仅在浏览器上查看少量数据时,此功能很有用。谢谢 ! (2认同)

Sel*_*cuk 20

根据DataTables文档,当您使用服务器端时,无法导出所有行:

关于服务器端处理的特别说明:在服务器端处理模式(serverSide)中使用DataTables时,selector-modifier对所选行的影响非常小,因为所有处理(排序,搜索等)都在服务器上执行.因此,客户端上存在的唯一行是任何时候在表中显示的行,并且选择器只能选择当前页面上的那些行.

我通过在长度菜单中添加"ALL"参数并培训最终用户在执行PDF(或XLS)导出之前显示所有记录来解决这个问题:

var table = $('#example').DataTable({
    serverSide: true,
    ajax: "/your_ajax_url/",
    lengthMenu: [[25, 100, -1], [25, 100, "All"]],
    pageLength: 25,
    buttons: [
        {
            extend: 'excel',
            text: '<span class="fa fa-file-excel-o"></span> Excel Export',
            exportOptions: {
                modifier: {
                    search: 'applied',
                    order: 'applied'
                }
            }
        }
    ],
    // other options
});
Run Code Online (Sandbox Code Playgroud)


hau*_*aui 6

这个按钮定义在滚动表(而不是分页)中对我有用:

{
  text: 'PDF',
  action: function(e, dt, button, config) {
    dt.one('preXhr', function(e, s, data) {
      data.length = -1;
    }).one('draw', function(e, settings, json, xhr) {
      var pdfButtonConfig = $.fn.DataTable.ext.buttons.pdfHtml5;
      var addOptions = { exportOptions: { "columns" : ":visible" }};

      $.extend(true,pdfButtonConfig,addOptions);
      pdfButtonConfig.action(e, dt, button, pdfButtonConfig);
    }).draw();
  }
}
Run Code Online (Sandbox Code Playgroud)

它将强制 DataTable 为一个请求请求当前过滤的所有行。然后它直接调用导出按钮的所需操作。该变量addOptions可用于更改导出按钮的标准配置。

如果您有很多行,因为它们都加载到 DOM 中,您可能会遇到问题。


dio*_*sgg 6

是的,完全有可能做到这一点。在内部,DataTables具有一个名为button.exportData()的函数。当您按下按钮时,将调用此函数并返回当前页面内容。您可以覆盖该函数,以便它根据当前过滤器提取所有服务器端结果。并调用用于ajax分页的相同URL。

您在初始化表之前将其覆盖。代码如下:

$(document).ready(function() {

    jQuery.fn.DataTable.Api.register( 'buttons.exportData()', function ( options ) {
            if ( this.context.length ) {
                var jsonResult = $.ajax({
                    url: 'myServerSide.json?page=all',
                    data: {search: $(#search).val()},
                    success: function (result) {
                        //Do nothing
                    },
                    async: false
                });

                return {body: jsonResult.responseJSON.data, header: $("#myTable thead tr th").map(function() { return this.innerHTML; }).get()};
            }
        } );

    $("#myTable ").DataTable(
        {
            "dom": 'lBrtip',
            "pageLength": 5, 
            "buttons": ['csv','print', 'excel', 'pdf'],
            "processing": true,
            "serverSide": true,
            "ajax": {
                "url": "myServerSide.json",
                "type": 'GET',
                "data": {search: $(#search).val()} 
            }
        }
});
Run Code Online (Sandbox Code Playgroud)