Row grouping with printing

Row grouping with printing

sciaschisciaschi Posts: 3Questions: 0Answers: 0
edited June 2017 in Free community support

I believe i solved the problem with printing with row grouping. I found a snippet of code on StackOverflow here and was able to fix it up to work with row grouping. This is placed in datatable-buttons.js on line 1564.

Heres some images of it working!
http://prntscr.com/fhx1vu
http://prntscr.com/fhx1ia

    var _exportData = function ( dt, inOpts )
    {

        var config = $.extend( true, {}, {
            rows:           null,
            columns:        '',
            grouped_array_index: [],
            modifier:       {
                search: 'applied',
                order:  'applied'
            },
            orthogonal:     'display',
            stripHtml:      true,
            stripNewlines:  true,
            decodeEntities: true,
            trim:           true,
            format:         {
                header: function ( d ) {
                    return strip( d );
                },
                footer: function ( d ) {
                    return strip( d );
                },
                body: function ( d ) {
                    return strip( d );
                }
            }

        }, inOpts );

        var strip = function ( str ) {
            if ( typeof str !== 'string' ) {
                return str;
            }

            // Always remove script tags
            str = str.replace( /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '' );

            if ( config.stripHtml ) {
                str = str.replace( /<[^>]*>/g, '' );
            }

            if ( config.trim ) {
                str = str.replace( /^\s+|\s+$/g, '' );
            }

            if ( config.stripNewlines ) {
                str = str.replace( /\n/g, ' ' );
            }

            if ( config.decodeEntities ) {
                _exportTextarea.innerHTML = str;
                str = _exportTextarea.value;
            }

            return str;
        };


        var header = dt.columns( config.columns ).indexes().map( function (idx) {
            var el = dt.column( idx ).header();
            return config.format.header( el.innerHTML, idx, el );
        } ).toArray();

        var footer = dt.table().footer() ?
            dt.columns( config.columns ).indexes().map( function (idx) {
                var el = dt.column( idx ).footer();
                return config.format.footer( el ? el.innerHTML : '', idx, el );
            } ).toArray() :
            null;

        var rowIndexes = dt.rows( config.rows, config.modifier ).indexes().toArray();
        var selectedCells = dt.cells( rowIndexes, config.columns );
        var cells = selectedCells
            .render( config.orthogonal )
            .toArray();
        var cellNodes = selectedCells
            .nodes()
            .toArray();

        var grouped_array_index     = config.grouped_array_index;                     //customised
        var no_of_columns           = header.length;
        var no_of_rows              = no_of_columns > 0 ? cells.length / no_of_columns : 0;
        var body                    = new Array( no_of_rows );
        var body_data               = new Array( no_of_rows );                                //customised
        var body_with_nodes         = new Array( no_of_rows );                          //customised
        var body_with_nodes_static  = new Array( no_of_rows );                          //customised
        var cellCounter             = 0;

        for (var i = 0, ien = no_of_rows; i < ien; i++)
        {
            var rows            = new Array( no_of_columns );
            var rows_with_nodes = new Array( no_of_columns );

            for ( var j=0 ; j<no_of_columns ; j++ )
            {
                rows[j]             = config.format.body( cells[ cellCounter ], i, j, cellNodes[ cellCounter ] );
                rows_with_nodes[j]  = config.format.body( cellNodes[ cellCounter ], i, j, cells[ cellCounter ] ).outerHTML;
                cellCounter++;
            }

            body[i]                     = rows;
            body_data[i]                = rows;
            body_with_nodes[i]          = $.parseHTML('<tr class="even">'+rows_with_nodes.join("")+'</tr>');
            body_with_nodes_static[i]   = $.parseHTML('<tr class="even">'+rows_with_nodes.join("")+'</tr>');
        }

        /******************************************** GROUP DATA *****************************************************/
        var row_array                       = dt.rows().nodes();
        var row_data_array                  = dt.rows().data();
        var iColspan                        = no_of_columns;
        var sLastGroup                      = "";
        var inner_html                      = '',
            grouped_index;
        var individual_group_array          = [],
            sub_group_array                 = [],
            total_group_array               = [];
        var no_of_splices                   = 0;  //to keep track of no of element insertion into the array as index changes after splicing one element

        for (var i = 0, row_length = body_with_nodes.length; i < row_length; i++)
        {
            sub_group_array[i]              = [];
            individual_group_array[i]       = [];

            var sGroup                      = '';

            for(var k = 0; k < grouped_array_index.length; k++)
            {
                sGroup                          = row_data_array[i][grouped_array_index[k]];
                inner_html                      = row_data_array[i][grouped_array_index[k]];
                grouped_index                   = k;
                individual_group_array[i][k]    = row_data_array[i][grouped_array_index[k]];
                sub_group_array[i][k]           = sGroup;
            }

            total_group_array[i] = sGroup;


            console.log("grouped_index",grouped_index);

            if ( sGroup !== sLastGroup )
            {
                var table_data              = [];
                var table_data_with_node    = '';

                for(var $column_index = 0;$column_index < iColspan;$column_index++)
                {
                    if($column_index === 0)
                    {
                        table_data_with_node        += '<td style="border-left:none;border-right:none">'+inner_html+'</td>';
                        table_data[$column_index]   = inner_html + " ";
                    }
                    else
                    {
                        table_data_with_node        += '<td style="border-left:none;border-right:none"></td>';
                        table_data[$column_index]   = '';
                    }
                }

                body_with_nodes.splice(i + no_of_splices, 0, $.parseHTML('<tr class="group group_'+grouped_index+' grouped-array-index_'+grouped_array_index[grouped_index]+'">'+table_data_with_node+'</tr>'));
                body_data.splice(i + no_of_splices, 0, table_data);
                no_of_splices++;
                sLastGroup = sGroup;
            }
        }

        return {
            header: header,
            footer: footer,
            body:   body_data
        };
    };

Usage:
Define grouped_array_index in exportOptions

 exportOptions: {
        // Any other settings used
        grouped_array_index: [<place row to use here>],
 },

Replies

  • allanallan Posts: 48,480Questions: 1Answers: 7,023 Site admin

    Thanks for this! There is also a pull request with this feature.

    Regards,
    Allan

  • cairoramos7cairoramos7 Posts: 1Questions: 0Answers: 0

    exportOptions: {
    // Any other settings used
    grouped_array_index: [<place row to use here>],
    },

    how to use this method to do the grouping?

  • rushidrautrushidraut Posts: 3Questions: 1Answers: 0

    My grouped Row is dynamically generated.
    Then how to use grouped_array_index:[<place row to use here>]

  • ckeggckegg Posts: 1Questions: 0Answers: 0

    This is what I did to print with rowGroup header.

    dataTables.buttons.js
    Line 1797
    to
    Line 1828

        var columns = header.length;
        var rows = columns > 0 ? cells.length / columns : 0;
        // var body = [ rows ]; // use body.push() method instead
        var body = [];
        var rowGroupHeader = null;
        var cellCounter = 0;
    
        // read rowGroup dataSrc
        var rowGroup_index = null;
        if (dt.settings()[0].rowGroup.dataSrc)
            rowGroup_index = dt.settings()[0].rowGroup.dataSrc();
    
        for ( var i=0, ien=rows ; i<ien ; i++ ) {
            var row = [ columns ];
    
            for ( var j=0 ; j<columns ; j++ ) {
    
                // Add group header
                if (rowGroup_index != null && j == rowGroup_index) {
                    if (rowGroupHeader != cells[ cellCounter ]) {
                        body.push( ['<td colspan="'+(columns-1)+'"><b>'+cells[ cellCounter ]+'</b></td>'] );
                        rowGroupHeader = cells[ cellCounter ];
                    }
                }
    
                row[j] = config.format.body( cells[ cellCounter ], i, j, cellNodes[ cellCounter ] );
                cellCounter++;
            }
    
            body.push(row);
            // body[i] = row;
        }
    
    
  • craigncraign Posts: 1Questions: 0Answers: 0
    edited January 16

    Hi there, thanks for posting this, I'm current integrating it into my own solution. Just a quick question though, should this work for nested groups? I noticed a few variables like sub_group_array which would imply such functionality, although am not too sure. Any light shed would be much appreciated.

  • maotanWangmaotanWang Posts: 1Questions: 0Answers: 0

    Have anybody can explain how to use grouped_array_index:[<place row to use here>] correctly, I place the datatable.buttons.js and add exportOptions, but it didn't work.

  • samlearn621samlearn621 Posts: 1Questions: 0Answers: 0

    Hi, I have tried to export with subheading (with rowGroup). But still no luck. Could someone point how to incorporate above changes clearly? as some other people said, I am not sure how to use " grouped_array_index:[<place row to use here>] ". Thanks.

  • elalgarroelalgarro Posts: 2Questions: 0Answers: 0

    @samelearn621 it's a custom attribute you add when initializing your table

    for example:

    $('#table-id').DataTable({
      buttons: [
        {
          extend: 'pdfHtml5',
          exportOptions: {
            //n is the index of the column you want to group by. 
            //for example if you want to group by the first col, you would use 0 for n
            grouped_array_index: [ n ] //note the brackets, i think this is so you can group by multiple columns. 
          }
        }
      ]
    })
    
  • elalgarroelalgarro Posts: 2Questions: 0Answers: 0

    spent some time working on this, cleaned up the code a bit. It seems like there's some additional functionality in this post that is either not used or not shown in this post's code snippet

    you should be able to paste this into the bottom of the _exportData function in datatables.buttons.js

    note, i changed the grouped_array_index to take an integer instead of an array.

                    var grouped_array_index     = config.grouped_array_index;
                            
                    if (grouped_array_index == undefined) { //don't run grouping logic if rows aren't grouped
                        return data
                    }
                    var no_of_columns           = header.length;
                var no_of_rows              = no_of_columns > 0 ? cells.length / no_of_columns : 0;
    
                var body_data               = new Array( no_of_rows );                                
                var body_with_nodes         = new Array( no_of_rows );                          
                var cellCounter             = 0;
             
                for (var i = 0, ien = no_of_rows; i < ien; i++)
                {
                    var rows            = new Array( no_of_columns );
                    var rows_with_nodes = new Array( no_of_columns );
             
                    for ( var j=0 ; j<no_of_columns ; j++ )
                    {
                        rows[j]             = config.format.body( cells[ cellCounter ], i, j, cellNodes[ cellCounter ] );
                        rows_with_nodes[j]  = config.format.body( cellNodes[ cellCounter ], i, j, cells[ cellCounter ] ).outerHTML;
                        cellCounter++;
                    }
                    body_data[i]                = rows;
                    body_with_nodes[i]          = $.parseHTML('<tr class="even">'+rows_with_nodes.join("")+'</tr>');
                }
             
                /******************************************** GROUP DATA *****************************************************/
                var row_array                       = dt.rows().nodes();
                var row_data_array                  = dt.rows().data();
                var iColspan                        = no_of_columns;
                var sLastGroup                      = "";
             
                var no_of_splices                   = 0;  //to keep track of no of element insertion into the array as index changes after splicing one element
             
                for (var i = 0, row_length = body_with_nodes.length; i < row_length; i++)
                {
                    var sGroup                      = row_data_array[i][grouped_array_index];
                    if ( sGroup !== sLastGroup )
                    {
                        var table_data              = [];
                        var table_data_with_node    = '';
             
                        for(var $column_index = 0;$column_index < iColspan;$column_index++)
                        {
                            if($column_index === 0)
                            {
                                                // strips anything inside < > tags. hoping this won't be an issue in the future. 
                                table_data[$column_index]   = sGroup.replace( /<[^>]*>/gi, '' ); + " ";
                            }
                            else
                            {
                                table_data[$column_index]   = '';
                            }
                        }
                        body_data.splice(i + no_of_splices, 0, table_data);
                        no_of_splices++;
                        sLastGroup = sGroup;
                    }
                }
             
                return {
                    header: header,
                    footer: footer,
                    body:   body_data
                };
    
Sign In or Register to comment.