How to Export Multiple Row Headers in jQuery Datatables?

 ̄綄美尐妖づ 提交于 2019-12-06 14:39:22

问题


Hi I am using jQuery Datatables 1.10. I am trying to export Datatable multiple header rows but not getting.But it is Exporting only second header row.I am using Buttons

  buttons: [{
                extend: 'excel',
                header: true

            }, {
                extend: 'print',
                header: true
            }
            ],

My table Structure like

                        <table id="example" style="color: black;" class="display compact cell-border" cellspacing="0">
                            <thead>

                                <tr>
                                    <th rowspan="2">Sl.No</th>
                                    <th rowspan="2">Zone</th>
                                    <th colspan="2">Allotted</th>
                                    <th colspan="2">Vacant</th>
                                    <th colspan="2">Amenities</th>
                                    <th colspan="2">Total</th>
                                </tr>

                                <tr>
                                    <th>No Of Plots</th>
                                    <th>Area</th>
                                    <th>No Of Plots</th>
                                    <th>Area</th>
                                    <th>No Of Plots</th>
                                     <th>Area</th>
                                    <th>No Of Plots</th>
                                    <th>Area</th>

                                </tr>
                            </thead>
                        </table>

回答1:


The mentioned solution on the DataTable-forum is not working for the latest version. I have adapted it in a way it works for me. I added a local function to buttons.html5.js:

var _fnGetHeaders = function(dt) {
    var thRows = $(dt.header()[0]).children();
    var numRows = thRows.length;
    var matrix = [];

    // Iterate over each row of the header and add information to matrix.
    for ( var rowIdx = 0;  rowIdx < numRows;  rowIdx++ ) {
        var $row = $(thRows[rowIdx]);

        // Iterate over actual columns specified in this row.
        var $ths = $row.children("th");
        for ( var colIdx = 0;  colIdx < $ths.length;  colIdx++ )
        {
            var $th = $($ths.get(colIdx));
            var colspan = $th.attr("colspan") || 1;
            var rowspan = $th.attr("rowspan") || 1;
            var colCount = 0;

            // ----- add this cell's title to the matrix
            if (matrix[rowIdx] === undefined) {
                matrix[rowIdx] = [];  // create array for this row
            }
            // find 1st empty cell
            for ( var j = 0;  j < (matrix[rowIdx]).length;  j++, colCount++ ) {
                if ( matrix[rowIdx][j] === "PLACEHOLDER" ) {
                    break;
                }
            }
            var myColCount = colCount;
            matrix[rowIdx][colCount++] = $th.text();

            // ----- If title cell has colspan, add empty titles for extra cell width.
            for ( var j = 1;  j < colspan;  j++ ) {
                matrix[rowIdx][colCount++] = "";
            }

            // ----- If title cell has rowspan, add empty titles for extra cell height.
            for ( var i = 1;  i < rowspan;  i++ ) {
                var thisRow = rowIdx+i;
                if ( matrix[thisRow] === undefined ) {
                    matrix[thisRow] = [];
                }
                // First add placeholder text for any previous columns.                 
                for ( var j = (matrix[thisRow]).length;  j < myColCount;  j++ ) {
                    matrix[thisRow][j] = "PLACEHOLDER";
                }
                for ( var j = 0;  j < colspan;  j++ ) {  // and empty for my columns
                    matrix[thisRow][myColCount+j] = "";
                }
            }
        }
    }

    return matrix;
};

Then I changed the code in DataTable.ext.buttons.excelHtml5 in the same file to:

    if ( config.header ) {
                /* ----- BEGIN changed Code ----- */ 
                var headerMatrix = _fnGetHeaders(dt);
                for ( var rowIdx = 0;  rowIdx < headerMatrix.length;  rowIdx++ ) {
                    addRow( headerMatrix[rowIdx], rowPos );
                }
                /* ----- OLD Code that is replaced: ----- */    
                //addRow( data.header, rowPos );
                /* ----- END changed Code ----- */  
                $('row c', rels).attr( 's', '2' ); // bold
    }



回答2:


Answer by @ronnie https://stackoverflow.com/a/42535830/5835910 is working. To make it work download the files from jquery datatable download builder https://datatables.net/download/index.

Please do not use files from example pages.




回答3:


Hi maybe I'm a little late but I hope my answer can help someone else. I exported all rows using an extra library, in my case, table2excel. I just copied the header rows using html() function and getting all the rows with .DataTable() function. The code looks as follows:

$("#exportExcel").click(function(){
    $('<table>')
    .append(
         $("#table1 thead").html()
     )
     .append(
        $("#table1").DataTable().$('tr').clone()
     )
     .table2excel({
        exclude: "",
        name: "casting",
        filename: "ExportedData.xls" 
     });
    });

It solved the problem in my case.




回答4:


Better to check this datatable documentation.Find below URL Export multiple row headers




回答5:


Adding to the solution that was given by Ronnie, since most of us got confused how exactly the approach works, would like to take it in a detail.

1) To get Excel button working add "buttons.html5.js", "dataTables.buttons.min.js", "jszip.min.js".

2) For multiple row header table export, add below function in "buttons.html5.js" at the botton of the document

var _fnGetHeaders = function(dt) {
    var thRows = $(dt.header()[0]).children();
    var numRows = thRows.length;
    var matrix = [];

    // Iterate over each row of the header and add information to matrix.
    for ( var rowIdx = 0;  rowIdx < numRows;  rowIdx++ ) {
        var $row = $(thRows[rowIdx]);

        // Iterate over actual columns specified in this row.
        var $ths = $row.children("th");
        for ( var colIdx = 0;  colIdx < $ths.length;  colIdx++ )
        {
            var $th = $($ths.get(colIdx));
            var colspan = $th.attr("colspan") || 1;
            var rowspan = $th.attr("rowspan") || 1;
            var colCount = 0;

            // ----- add this cell's title to the matrix
            if (matrix[rowIdx] === undefined) {
                matrix[rowIdx] = [];  // create array for this row
            }
            // find 1st empty cell
            for ( var j = 0;  j < (matrix[rowIdx]).length;  j++, colCount++ ) {
                if ( matrix[rowIdx][j] === "PLACEHOLDER" ) {
                    break;
                }
            }
            var myColCount = colCount;
            matrix[rowIdx][colCount++] = $th.text();

            // ----- If title cell has colspan, add empty titles for extra cell width.
            for ( var j = 1;  j < colspan;  j++ ) {
                matrix[rowIdx][colCount++] = "";
            }

            // ----- If title cell has rowspan, add empty titles for extra cell height.
            for ( var i = 1;  i < rowspan;  i++ ) {
                var thisRow = rowIdx+i;
                if ( matrix[thisRow] === undefined ) {
                    matrix[thisRow] = [];
                }
                // First add placeholder text for any previous columns.                 
                for ( var j = (matrix[thisRow]).length;  j < myColCount;  j++ ) {
                    matrix[thisRow][j] = "PLACEHOLDER";
                }
                for ( var j = 0;  j < colspan;  j++ ) {  // and empty for my columns
                    matrix[thisRow][myColCount+j] = "";
                }
            }
        }
    }

    return matrix;
};

2) With in the same file find "DataTable.ext.buttons.excelHtml5" and replace the code block

if(config.header){
    /*Existing code*/
  }

to

if ( config.header ) {
                /* ----- BEGIN changed Code ----- */ 
                var headerMatrix = _fnGetHeaders(dt);
                for ( var rowIdx = 0;  rowIdx < headerMatrix.length;  rowIdx++ ) {
                    addRow( headerMatrix[rowIdx], rowPos );
                }
                /* ----- OLD Code that is replaced: ----- */    
                //addRow( data.header, rowPos );
                /* ----- END changed Code ----- */  
                $('row c', rels).attr( 's', '2' ); // bold
    }

Thats it. you would be able to export the multiple header rows.

and adding to the above if you want to export merged cells then below code would help you.

add this to buttons customize function.

buttons: [
{
    extend: 'excel', 
    customize: function (xlsx) {

                        //Apply styles, Center alignment of text and making it bold.

                        var sSh = xlsx.xl['styles.xml'];

                        var lastXfIndex = $('cellXfs xf', sSh).length - 1;



                        var n1 = '<numFmt formatCode="##0.0000%" numFmtId="300"/>';

                        var s2 = '<xf numFmtId="0" fontId="2" fillId="0" borderId="0" applyFont="1" applyFill="0" applyBorder="0" xfId="0" applyAlignment="1">' +

                            '<alignment horizontal="center"/></xf>';

                            '<alignment horizontal="center"/></xf>';

                        sSh.childNodes[0].childNodes[0].innerHTML += n1;

                        sSh.childNodes[0].childNodes[5].innerHTML += s2;



                        var greyBoldCentered = lastXfIndex + 1;



                        //Merge cells as per the table's colspan

                        var sheet = xlsx.xl.worksheets['sheet1.xml'];

                        var dt = $('#tblReport').DataTable();

                        var frColSpan = $(dt.table().header()).find('th:nth-child(1)').prop('colspan');

                        var srColSpan = $(dt.table().header()).find('th:nth-child(2)').prop('colspan');

                        var columnToStart = 2;



                        var mergeCells = $('mergeCells', sheet);

                        mergeCells[0].appendChild(_createNode(sheet, 'mergeCell', {

                            attr: {

                                ref: 'A1:' + toColumnName(frColSpan) + '1'

                            }

                        }));

                        mergeCells.attr('count', mergeCells.attr('count') + 1);



                        var columnToStart = 2;

                        while (columnToStart <= frColSpan) {

                            mergeCells[0].appendChild(_createNode(sheet, 'mergeCell', {

                                attr: {

                                    ref: toColumnName(columnToStart) + '2:' + toColumnName((columnToStart - 1) + srColSpan) + '2'

                                }

                            }));

                            columnToStart = columnToStart + srColSpan;

                            mergeCells.attr('count', mergeCells.attr('count') + 1);

                        }



                        //Text alignment to center and apply bold

                        $('row:nth-child(1) c:nth-child(1)', sheet).attr('s', greyBoldCentered);

                        for (i = 0; i < frColSpan; i++) {

                            $('row:nth-child(2) c:nth-child(' + i + ')', sheet).attr('s', greyBoldCentered);

                        }



                        function _createNode(doc, nodeName, opts) {

                            var tempNode = doc.createElement(nodeName);



                            if (opts) {

                                if (opts.attr) {

                                    $(tempNode).attr(opts.attr);

                                }



                                if (opts.children) {

                                    $.each(opts.children, function (key, value) {

                                        tempNode.appendChild(value);

                                    });

                                }



                                if (opts.text !== null && opts.text !== undefined) {

                                    tempNode.appendChild(doc.createTextNode(opts.text));

                                }

                            }



                            return tempNode;

                        }



                        //Function to fetch the cell name

                        function toColumnName(num) {

                            for (var ret = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) {

                                ret = String.fromCharCode(parseInt((num % b) / a) + 65) + ret;

                            }

                            return ret;

                        }



                    }
}
]


来源:https://stackoverflow.com/questions/40302985/how-to-export-multiple-row-headers-in-jquery-datatables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!