How to export all rows from Datatables using Ajax?
Asked Answered
E

13

45

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

The problem is that it only export the page that is currently displayed.

I am exporting like this:

buttons: [
    {
        extend: 'pdfHtml5',
        text: 'PDF',
        exportOptions: {
            "columns": ':visible',
        }
    },
]

How can I export all rows?

Epic answered 21/9, 2015 at 10:13 Comment(2)
Are you using server-side processing, i.e. do you have serverSide: true in your initialization options?Aventine
There was download plug-in for retired TableTools extension that allowed to generate PDF in server-side processing mode. With new Buttons extension that replaced TableTools, there is no documentation for similar functionality.Aventine
W
30

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
});
Whisenant answered 23/10, 2015 at 11:50 Comment(1)
thanks but I have figured it out from your answer. Thank you, sir. 1+Mares
E
66

Thanks a lot to the user "kevinpo". He has given the way how all records from jquery datatable to be downloaded as excel when server side processing is On. Based on his answer, here i have complete export functionality implemented (copy, excel, csv, pdf, print) for server side processing.

inside $(document).ready() define the below function & call this function on action of each export button like below :

/* 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

And for buttons, define like below

"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
            }],

That's it. Now your download is ready.

Excitor answered 3/8, 2019 at 5:25 Comment(12)
Worked perfectly for me after failing at the other high voted answers...I really need to get better with jsTaffy
Works like magic! What an amazing function... You deserve more than a like!Hamman
It triggers popup blocker on FF and Safari Mac. For Safari there is an easy fix, replace $.fn.dataTable.ext.buttons.print.action(e, dt, button, config); with setTimeout(function(){ $.fn.dataTable.ext.buttons.print.action(e, dt, button, config); }, 0);but not for FF.Oversee
This answer should be one with highest vote. This saved me hours of work. KudosOxfordshire
An improvement would be to change the data.length to the actual number of records in the datatable instead of a big random number: data.length = $('#id').DataTable().page.info().recordsTotal;Borne
@Borne You do not need the DataTable id, you can use dt like data.length = dt.page.info().recordsTotal;Goingover
Thank you Chandan! Works perfect! Exports all the records when paginated.Pimentel
Works like a charm! struggling from 2 days and got fixing in 2 minutes :) Thanks for the solution.Lactescent
Thank you for your solutions. Data is exported properly but their ordering is changed while exporting. Please help me out of this.Earphone
This answer deserves tons of gold badges! I don't remember I have used a more simple and quick plug n play code ever in my life. Works like a cake!Triclinium
Is it possible to make it so that when you export to PDF, it exports in 'landscape' instead of 'portrait'?Infiltrate
Waooo.... It works perfect.Boyle
S
58

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
        },
Shih answered 19/6, 2017 at 15:55 Comment(13)
In my situation this code work only for excel button, other buttons such as pdf or csv this code doesn't workDoura
@Жасулан Бердибеков change.. if (button[0].className.indexOf('buttons-excel') >= 0) { to if (button[0].className.indexOf('buttons-excel') >= 0 || button[0].className.indexOf('buttons-csv') >= 0) {Gunter
Best Answer !! Managed to do it and exporting 30k rows only in a few second, but can u show me how to export to pdf? managed to do it with excel and csv, but when trying to generate pdf, the pdf files is corruptInterlaminate
This is useful when you want to export all data while viewing only few data on browser. Thanks !Maye
Excellent solution, but I'm OOM server side with 48k records.Kuehn
@ChandanKumar are you able to extend the excel button with an explicit function as the action as in datatables.net/forums/discussion/44675/…?Shih
@Shih Yes I do. As mentioned in the last message... everything works for me except exporting all records. Currently it exports only visible 10 rowsExcitor
@ChandanKumar if you are able to extend it with an explicit function, then add your debugger statement to that function and work from there. It sounds like something is not wired up correctly and the newExportAction is not being fired. If you are having trouble getting custom code to fire then that should probably be a separate StackOverflow question.Shih
@Shih : I made it work for these export buttons(excel,csv,pdf,print). But for "COPY" it is not working. Can you pls help me on thisExcitor
I feel like such a novice I can't even get the newExportAction called when extending the buttons yet I know the extended button block is being executed...Taffy
Unfortunately it will trigger popup blocker on Safari Mac, but luckily there is an easy fix: in oldExportAction replace $.fn.dataTable.ext.buttons.print.action(e, dt, button, config); with setTimeout(function(){ $.fn.dataTable.ext.buttons.print.action(e, dt, button, config); }, 0);Oversee
Great solution, live saver!Rafaelle
This is useful for print,excel,csv, copy. when you want to export all data.Brewage
W
30

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
});
Whisenant answered 23/10, 2015 at 11:50 Comment(1)
thanks but I have figured it out from your answer. Thank you, sir. 1+Mares
A
9

Yes, it's totally possible to make this work. Internally, DataTables has a function called buttons.exportData(). When you press a button, this function is called and returns the current page content. You can overwrite that function so it pulls all server side results based on current filters. And calling the same url used for ajax pagination.

You overwrite it before initializing your table. The code is as follows:

$(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()} 
            }
        }
});
Abatis answered 25/1, 2017 at 21:23 Comment(2)
If you need to distinguish between different DataTable objects, you can use this.table().node().id inside the function to obtain the table id.Prudhoe
@RobertHume Where do I put this line this.table().node().idDredger
B
6

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.

Boston answered 30/6, 2016 at 15:26 Comment(0)
T
4

I know this is an old question, however for anyone struggling with this, here's my solution.

Variables:

var downloading = false,
    downloadTimestamp = null;

Download button definition:

buttons: [{
    text: '<span class="glyphicon glyphicon-save-file" aria-hidden="true"></span>',
    titleAttr: 'CSV',
    className: 'downloadCSV',
    action: function(e, dt, node, config) {
        if (downloading === false) { //if download is in progress, do nothing, else
            node.attr('disabled', 'disabled'); //disable download button to prevent multi-click, probably some sort of *busy* indicator is a good idea

            downloading = true; //set downloading status to *true*

            dt.ajax.reload(); //re-run *DataTables* AJAX query with current filter and sort applied
        }
    }
}]

Ajax definition:

ajax: {
    url: ajaxURL,
    type: 'POST',
    data: function(data) {
        data.timestamp = new Date().getTime(); //add timestamp to data to be sent, it's going to be useful when retrieving produced file server-side

        downloadTimestamp = data.timestamp; //save timestamp in local variable for use with GET request when retrieving produced file client-side

        if (downloading === true) { //if download button was clicked
            data.download = true; //tell server to prepare data for download
            downloading = data.draw; //set which *DataTable* draw is actually a request to produce file for download
        }

        return { data: JSON.stringify(data) }; //pass data to server for processing
    }
}

'preDrawCallback' function:

preDrawCallback: function(settings) {
    if (settings.iDraw === downloading) { //if returned *DataTable* draw matches file request draw value
        downloading = false; //set downloading flag to false

        $('.downloadCSV').removeAttr('disabled'); //enable download button

        window.location.href = ajaxURL + '?' + $.param({ ts: downloadTimestamp }); //navigate to AJAX URL with timestamp as parameter to trigger file download. Or You can have hidden IFrame and set its *src* attribute to the address above.

        return false; //as it is file request, table should not be re-drawn
    }
}

Server-side:

if(download == false), then server executes SELECT columns FROM tables WHERE rowNumber BETWEEN firstRow AND lastRow and outputs result for normal display within DataTable.

if(download == true), then server executes SELECT columns FROM tables and stores all rows formatted as CSV file (or any other file format depending on what Your server environment is capable to produce) server-side for later retrieval by GET request.

Following is ASP JScript code that I've used server-side:

    var timestamp = Number(Request.QueryString('ts')), //if it's a GET request, get timestamp
        tableData = {
            draw: data.draw,
            recordsTotal: 100, //some number static or dynamic
            recordsFiltered: 10, //some number static or dynamic
            data: []
        };
        jsonData = String(Request.Form('data')), //if it's POST request, get data sent by *DataTable* AJAX
        data = jsonData === 'undefined' || jsonData.length === 0 ? null : JSON.parse(jsonData); //do some error checking (optional)

    if(!isNaN(timestamp)) { //check timestamp is valid
        var csvTextKey = 'download-' + timestamp, //this is where timestamp value is used (can be any other unique value)
            csvText = Session(csvTextKey); //obtain saved CSV text from local server-side storage

        if(typeof csvText === 'undefined') { //if CSV text does not exist in local storage, return nothing (or throw error is You wish)
            Response.End();
        }

        //if CSV exists:
        Response.ContentType = 'text/csv'; //set response mime type
        Response.AddHeader('Content-Disposition', 'attachment; filename=test.csv'); //add header to tell browser that content should be downloaded as file and not displayed

        Response.Write(csvText); //send all content to browser

        Response.End(); //stop further server-side code execution
    }

    //if timestamp is not valid then we assume this is POST request, hence data should be either prepared for display or stored for file creation

    if(typeof data !== 'object' || data === null) { //do some more clever error checking
        throw 'data is not an object or is null';
    }

        var recordset = data.download === true ? sqlConnection.Execute('SELECT * FROM #FinalTable') : Utilities.prepAndRunSQLQuery('SELECT * FROM #FinalTable WHERE rowId BETWEEN ? AND ?', [data.start, data.start + data.length], //execute SELECT either for display or for file creation
            headerRow = [],
            sqlHeaderRow = [],
            exportData = [];; 

        if(data.download === true) { //create CSV file (or any other file)
            if(!Array.isArray(data.columns)) {
                throw 'data.columns is not an array';
            }

            for(var i = 0, dataColumnsCount = data.columns.length; i < dataColumnsCount; ++i) {
                var dataColumn = data.columns[i], //get columns data object sent by client
                    title = dataColumn.title, //this is custom property set on client-side (not shown in code above)
                    sqlColumnName = typeof dataColumn.data === 'string' ? dataColumn.data : (typeof dataColumn.data.display === 'string' ? dataColumn.data.display : dataColumn.data['_']); //set SQL table column name variable

                if(typeof title === 'string' && typeof sqlColumnName === 'string' && columnNames.indexOf(sqlColumnName) > -1) { //some more error checking
                    headerRow.push(title);
                    sqlHeaderRow.push(sqlColumnName);
                }
            }

            exportData.push('"' + headerRow.join('","') + '"'); //add table header row to in CSV file format
        }

        while(recordset.EOF === false) { //iterate through recordset
            if(data.download === true) { //if download flag is set build string containing CSV content
                var row = [];

                for(var i = 0, count = sqlHeaderRow.length; i < count; ++i) {
                    row.push(String(recordset.Fields(sqlHeaderRow[i]).Value).replace('"', '""'));
                }

                exportData.push('"' + row.join('","') + '"');
            }

            else { //else format data for display
                var row = {};

                for(var i = 1, fieldsCount = recordset.Fields.Count; i < fieldsCount; ++i) {
                    var field = recordset.Fields(i),
                        name = field.Name,
                        value = field.Value;

                    row[name] = value;
                }

                tableData.data.push(row);
            }

            recordset.MoveNext();
        }

if(data.download === true) { //save CSV content in server-side storage
    Session('download-' + data.timestamp) = exportData.join('\r\n'); //this is where timestamp value is used (can be any other unique value)
}

Response.Write(JSON.stringify(tableData)); //return data for display, if download flag is set, tableData.data = []
Toandfro answered 3/8, 2016 at 15:18 Comment(0)
S
2

If you use Laravel framework, you can use this....

$.fn.DataTable.Api.register( 'buttons.exportData()', function( options ) {
  if(this.context.length) {

    var src_keyword = $('.dataTables_filter input').val();

    // make columns for sorting
    var columns = [];
    $.each(this.context[0].aoColumns, function(key, value) {
      columns.push({
        'data' : value.data, 
        'name' : value.name, 
        'searchable' : value.bSearchable, 
        'orderable' : value.bSortable
      });
    });

    // make option for sorting
    var order = [];
    $.each(this.context[0].aaSorting, function(key, value) {
      order.push({
        'column' : value[0], 
        'dir' : value[1]
      });
    });

    // make value for search
    var search = {
      'value' : this.context[0].oPreviousSearch.sSearch, 
      'regex' : this.context[0].oPreviousSearch.bRegex
    };

    var items = [];
    var status = $('#status').val();
    $.ajax({
      url: "server_side_url",
      data: { columns: columns, order: order, search: search, status: status, page: 'all' }
      success: function (result) {

        $.each(result.data, function(key, value) {

          var item = [];

          item.push(key+1);
          item.push(value.username);
          item.push(value.email);
          item.push(value.created_at);
          item.push(value.status);

          items.push(item);
        });
      },
      async: false
    });

    return {
      body: items, 
      // skip actions header
      header: $("#user_table thead tr th").map(function() { 
        if(this.innerHTML!='Actions')
          return this.innerHTML; 
      }).get()
    };
  }
});

var user_table = $('#user_table').DataTable({
  dom: 'Bfrtip',
  buttons: [
  'copy', 'csv', 'excel', 'pdf', 'print'
  ],
  "oSearch": {"bSmart": false},
  processing: true,
  serverSide: true,
  ajax: {
    url: "server_side_url",
    type: 'GET',
    data: function (d) {
      d.status = ""; // when onload make status as empty to get all users
    }
  },
  columns: [
  {data: 'DT_RowIndex', name: 'DT_RowIndex'},
  {data: 'username', name: 'username'},
  {data: 'email', name: 'email'},
  {data: 'created_at', name: 'created_at'},
  {data: 'status', name: 'status'},
  {data: 'actions', name: 'actions', orderable: false, searchable: false},
  ],
});

// filter users with status
$('#status').change(function() {
  user_table.draw();
});
Sarcomatosis answered 16/8, 2019 at 13:33 Comment(2)
Can you explain how this works? How to answerErnestineernesto
"Brevity is acceptable, but fuller explanations are better." How do I write a good answer?. Stack Overflow values full and complete answers. You can edit your answer here or click the "edit" button in the bottom left corner of your answer. Thanks.Ernestineernesto
M
0

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
}); 
Malamute answered 27/12, 2016 at 4:27 Comment(0)
D
0

I'm using Datatables Version: 1.10.15, and got @kevenpo's answer to work. I had to modify it a bit to handle our server-side parameters, but that was the only stumbling block. I changed his line: data.length = 2147483647; to data.params[2]= -1; because we stored our server-side parameters in a params sub-array. I have not tested it yet with a very large dataset to see what the performance is, but this is a very clever solution.

Dexterdexterity answered 11/7, 2017 at 13:42 Comment(1)
Please format your answer correctly with the help of the Stackoverflow editorMccrae
I
0

Just wanted to post an actual answer for people struggling with this.

If you are exporting using the excel button, you can use the customizeData button property to format the data going to excel a moment before it exports.

I used this to make a synchronous api call to my server to get the data, return it, massage it, and then let it continue on it's way. Code below.

                           {
                extend: 'excel',
                customizeData: function (p)
                {
                    //get the params for the last datatables ajax call
                    var params = JSON.parse(options.dataTable.ajax.params());
                    //flag to tell the server to ignore paging info and get everything that matches the filter
                    params.export = true;
                    UC.Api(options.api.read.getHook(), params, function (data)
                    {
                        p.body = new Array();
                        $.each(data.data, function (i, d)
                        {
                            var item = [d.serial, UC.FormatDateToLocal(d.meta.Date), d.transmission.title, d.transmission.type, d.transmission.information];
                            p.body.push(item);
                        });
                    }, null, { async: false });
                }
            },
Ism answered 4/1, 2018 at 16:15 Comment(0)
T
0

@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', ...]
      }
    }
  });
Thirtyeight answered 3/9, 2019 at 0:55 Comment(0)
H
0

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

Helmsman answered 25/10, 2019 at 12:9 Comment(0)
J
0

it will works

// Define this Before initialization of DataTable

jQuery.fn.DataTable.Api.register('buttons.exportData()', function (options) {
            if (this.context.length) {
                let excelDatas = [];
                //--------------------------Getting - Data-Table-Existing-Prameters--------------------------------//
                let execlParams = this.ajax.params();
                execlParams.export = true; // in database query don't set limit if export is true;
                //--------------------------------------------------------------------------------------------------//
                var jsonResult = $.ajax({
                    "type": "POST",
                    url: URL_load,
                    data: execlParams,
                    success: function (result) {
                        let ReposneData = JSON.parse(result);
                        let stateData = ReposneData.data;
                        (stateData).map((row, index) => {
                            var item = [row.name];
                            excelDatas.push(item);
                        });
                    },
                    async: false
                });
                return {
                    body: excelDatas,
                    header: ['Name']
                };
            }
        });
Jovita answered 1/10, 2022 at 11:23 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Malaspina

© 2022 - 2024 — McMap. All rights reserved.