How to export all rows from DataTables using server side (ajax)

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.

However, it is possible to actually override some DataTable internal method to make this happen, without modifying its source code. More specifically, you override the method responsible for extracting the current’s page lines to actually pull the  data from your server side.

You have to add the code for overriding the export just before initializing your dataTable. The final code would look like this:

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

Let’s remember there are two ways to handle Ajx json data on DataTables. The first and easier to make the export happen, is to use arrays. If you’re using objects, you have to parse them into arrays, because the buttons.exportData() function is supposed to return the data in array. (Like this ->  [[1, “John”], [2, “Jen”], [3, “Ross”]])

12 Comments

  1. naman gupta says:

    only pdf export is working with this method. Have you checked the same thing for other methods(csv,excel,print) too?

    Like

    1. diogenesgg says:

      All export methods are supposed to work using this strategy. What error gets out in browser console when trying to export using csv, for example?

      Like

  2. Vladimir says:

    on this line
    data: {search: $(#search).val()},
    I get “invalid character” on #. Tried changing it to
    data: {search: $(“#search”).val()}, which removes the error, but export buttons wont create the file in this instance.

    Liked by 1 person

  3. diogenesgg says:

    Thank you for noticing this double quote.
    Make sure the “body” attribute (in the return for Api.register) is an array of array, like the following:

    [
    [“John Doe”, 0, 0, 0, 0, 0, “0.00”, 0]
    [“Bob Doe”, 0, 0, 0, 0, 0, “0.00”, 0]
    [“Alice Doe”, 0, 0, 0, 0, 0, “0.00”, 0]
    ]

    Like

  4. ife2blog says:

    I was facing the same trouble of Vladmir until I noticed diogenesgg note about the Array expected return of Ajax.
    My code was returning an Object instead of an Array, than I solved it replacing the following code in return:

    body: jsonResult.responseJSON.data

    by:

    body: jsonResult.responseJSON.data.map(el => Object.keys(el).map(key => el[key]))

    I had to search how to do that ’cause I didn’t know how to parse an Array of Objects into an Array of Arrays, so I’m recording it here. Maybe it can be useful to someone else.

    Liked by 1 person

    1. optimisticjohn says:

      Thanks a lot. It help me a lot to display the data.

      Like

  5. cheng wai loon says:

    i get an error Uncaught TypeError: Cannot assign to read only property ‘0’ of string..any idea about it?

    Like

  6. Anadi Chakraborty says:

    I am getting expected result for some grids. but for few cases there are mismatches between header and values like in Header A i am having value of header B and so on.

    Liked by 1 person

  7. Pavlo says:

    Works like a charm! Thank you.
    However, like ife2blog has noticed, body: jsonResult.responseJSON.data
    should be replaced by:
    body: jsonResult.responseJSON.data.map(el => Object.keys(el).map(key => el[key]))

    Liked by 1 person

  8. optimisticjohn says:

    Thanks for resolving the issue of Printing all the data from serverside . I have your code to export all that I received from serverside. But I got into another problem. I was successful to print all the data I receive from external source. But the problem is that I have 4 JQuery DataTables on one page and “jQuery.fn.DataTable.Api.register(‘buttons.exportData()'” binds this event with all the Datatables. Is there any way I can make it available to one datatable.

    Liked by 1 person

  9. Rajkumar says:

    how to exclude the columns while export in server side process

    Like

Leave a Comment