How to export all rows from Datatables using Ajax?

前端 未结 12 1148
广开言路
广开言路 2020-11-29 23:38

I am using new feature in Datatables: \"HTML5 export buttons\". I am loading data with Ajax.

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

相关标签:
12条回答
  • 2020-11-29 23:55

    The answer of Selcuk will work absolutely fine if we can fix the value of "All" beforehand. Suppose the number of rows is stored in variable row_count. Then

    var row_count = $("#row_count").val();
    var table = $('#example').DataTable({
        serverSide: true,
        ajax: "/your_ajax_url/",
        lengthMenu: [[25, 100, row_count], [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
    }); 
    
    0 讨论(0)
  • 2020-11-29 23:56

    @diogenesgg answer is good!

    but I checked $.fn.DataTable.Api.register dont support Promise

    So, I fetched data first.

        const {data} = await selectDailyConnectStatistics({
          page: 1,
          limit: 99999999
        }))
        excelDatas = data.list
    
        $("#table").DataTable().button('.buttons-excel').trigger();
    

    Second trigger excel export.

      let excelDatas = []
      $.fn.DataTable.Api.register('buttons.exportData()', function(options) {
        if (this.context.length ) {
          return {
            body: _.map(excelDatas, v=> [v.data, ...]), 
            header: ['colum header name', ...]
          }
        }
      });
    
    0 讨论(0)
  • 2020-11-29 23:57

    you can make a hidden extra table in your page then make a button for download all data , assign this code for make hidden table as datatable with all rows with these options

    var options = {
                "processing": true,
                "serverSide": true,
                "ajax": fullbase,
                "language": {
                    "search": "Buscar: ",
                    "zeroRecords": "Datos no encontrados."
                },
                "initComplete": function(settings, json) {
                    $(".buttons-excel").click();
                },
                "iDisplayLength": 100000,
                lengthMenu: [[10,25,50,100, 100000], [10,25,50, 100, "All"]],
                "buttons": [{
                    extend : 'excel',
                    exportOptions : {
                            order : 'current',  
                            page : 'all',    
                            search : 'none' 
                    }
                }],
                "dom": "Blfrtip",
            };
    

    you can see a trigger on export excel button in complete table event and will run automatically for user when user click on that button then get an excel with all data

    0 讨论(0)
  • 2020-11-29 23:58

    According to DataTables documentation there is no way to export all rows when you are using server side:

    Special note on server-side processing: When using DataTables in server-side processing mode (serverSide) the selector-modifier has very little effect on the rows selected since all processing (ordering, search etc) is performed at the server. Therefore, the only rows that exist on the client-side are those shown in the table at any one time, and the selector can only select those rows which are on the current page.

    I worked this around by adding an 'ALL' parameter to the length menu and training end users to display all records before doing a PDF (or XLS) export:

    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
    });
    
    0 讨论(0)
  • 2020-11-30 00:05

    You need to tell the AJAX function to get all data, then do the export but cancel the actual draw so that all of that data isn't loading into the DOM. The full data will still exist in memory for the DataTables API though, so you need to refresh it to the way it was before the export.

    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();
    };
    

    and:

        buttons: [
            {
                extend: 'excel',
                action: newExportAction
            },
    
    0 讨论(0)
  • 2020-11-30 00:09

    This button definition worked for me in a scrolled table (instead of paging):

    {
      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();
      }
    }

    It will force the DataTable to request all rows for the current filtering for one request. Then it calls the desired action of the Export button directly. The variable addOptions can be used to alter the standard configuration of the export button.

    You might run into problems though if you have a lot of rows as they are all loaded into the DOM.

    0 讨论(0)
提交回复
热议问题