如何在jQuery数据表中导出多个行标题?

mwg9r5ms  于 2022-12-12  发布在  jQuery
关注(0)|答案(9)|浏览(188)

嗨,我正在使用jQuery Datatables 1.10。我正在尝试导出Datatable的多个标题行,但没有得到。但它只导出了第二个标题行。我正在使用按钮:

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

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

My table结构类似

<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>
toe95027

toe950271#

上面提到的solution on the DataTable-forum不适用于最新版本。我已经将其修改为适合我的方式。我在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;
};

然后,我将同一文件中DataTable.ext.buttons.excelHtml5中的代码更改为:

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
    }
f2uvfpb9

f2uvfpb92#

由于我们大多数人都搞不清楚这种方法到底是如何工作的,所以我想详细介绍一下Ronnie给出的解决方案。
1.要使Excel按钮工作,请添加buttons.html5.jsdataTables.buttons.min.jsjszip.min.js
1.对于多行表头表导出,在文档底部的buttons.html5.js中添加below函数

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

1.在同一文件中使用查找DataTable.ext.buttons.excelHtml5并替换代码块

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

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
}

就是这样。您可以导出多个标题行。
如果你想导出合并的单元格,下面的代码将帮助你。
将此功能添加到按钮自定义功能中。

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>';

            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;
            }
        }
    }
]
ijxebb2r

ijxebb2r3#

答案由@ronnie https://stackoverflow.com/a/42535830/5835910是工作。要使它工作下载文件从jquery数据表下载构建器https://datatables.net/download/index
请不要使用示例页面中的文件。

nbewdwxp

nbewdwxp4#

嗨,也许我有点晚了,但我希望我的回答能帮助其他人。我使用一个额外的库导出了所有行,在我的例子中是table2excel。我只是使用**html()函数复制了标题行,并使用.DataTable()**函数获取了所有行。代码如下所示:

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

它解决了我的问题。

lf3rwulv

lf3rwulv5#

最好查看此数据表文档。请在下面找到URL Export multiple row headers

piah890a

piah890a6#

我创建了一个自定义buttons.html5.js(基于Ronnie的解决方案),它允许Excel导出中的多个页眉和页脚
https://gist.github.com/emersonmoretto/41993309f74a4b09f8e90c0a541de342

46scxncf

46scxncf7#

你好,我迟到了,但我发现了一个简单的解决方案,由https://stackoverflow.com/a/56370447。是的,它不是dataTable库,但希望它能帮助一些开发人员谁正在寻找另一个解决方案。
我刚刚将值从“my_id_table_to_export”更改为
<a href="#" onclick="download_table_as_csv('my_id_table_to_export');">Download as CSV</a>
到'示例'(dataTable ID)
<a href="#" onclick="download_table_as_csv('example');">Download as CSV</a>
然后我调用了函数(请看上面的解决方案)

uqdfh47h

uqdfh47h8#

由于这是此问题的最佳搜索结果,因此我想分享一下我的解决方法。
数据库导出函数将从最后一个标题行开始。即使最后一行被隐藏,它也会这样做!
因此,解决此问题的一个非常简单的方法是向标题中再添加一行,为其给予要导出的列名,然后隐藏该行。
例如:

<thead>
  <tr>...Your first header row...</tr>
  <tr>...Your second header row...</tr>
  <tr style="display: none;">
    <th>Column 1 export-friendly name</th>
    <th>Column 2 export-friendly name</th>
    <th>etc..</th>
  </tr>
</thead>

它仍然只导出一个标题行,但这样您至少可以控制导出标题的内容。
编辑:刚刚意识到排序也应用于最后一列,因此如果它被隐藏,您将无法排序。添加“bSortCellsTop:true”添加到配置中应该可以解决这个问题。
编辑2:抱歉,没关系。添加bSortCellsTop:false完全破坏了整个解决方案。哇,真是一团糟。

20jt8wwn

20jt8wwn9#

打印时使用按钮中的自定义功能。因为DataTable只支持一个标题行。

{
        extend: 'print',
        exportOptions: {
            columns: [ 0, 1, 2, 3, 4, 5, 6, 7, 8,9 ]
        },
        text: 'Print',
        header: true,
        className: 'btn btn-default btn-xs',
        sheetName: 'data',
        attr: {
            id: 'print'
        },
        filename: function() {
            return $('#print').data('filename');
        },
        customize: function ( win ) {
            $(win.document.body).find( 'thead' ).prepend(`
                <tr class="">
                    <th colspan="5" >Title: {{$title}}</th>
                    <th colspan="2">Date: {{Request::get('from')}}</th>
                    <th colspan="2">Total guests: {{$guests_list->count()}}</th>
                    <th></th>
                    <th></th>
                </tr>
            `);
        }

相关问题