您好,我正在使用 jQuery Datatables 1.10。我正在尝试导出 Datatable 多个标题行但没有得到。但它仅导出第二个标题行。我正在使用按钮:
buttons: [{
extend: 'excel',
header: true
}, {
extend: 'print',
header: true
}],
我的表结构像
<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>
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
}
添加到 Ronnie 给出的解决方案中,因为我们大多数人都对这种方法的工作原理感到困惑,所以想详细了解一下。
要让 Excel 按钮工作,请添加
buttons.html5.js
、dataTables.buttons.min.js
、jszip.min.js
.多行表头导出,在文档底部的
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){
/*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;
}
}
}
]
@ronnie 的回答https://stackoverflow.com/a/42535830/5835910 正在工作。 要使其正常工作,请从 jquery 数据表下载生成器下载文件https://datatables.net/download/index.
请不要使用示例页面中的文件。
嗨,也许我来晚了一点,但我希望我的回答可以帮助别人。 我使用额外的库导出所有行,在我的例子中是 table2excel。 我只是使用 html() 函数复制标题行,并使用 .DataTable() 函数获取所有行。代码如下所示:
$("#exportExcel").click(function(){
$('<table>')
.append(
$("#table1 thead").html()
)
.append(
$("#table1").DataTable().$('tr').clone()
)
.table2excel({
exclude: "",
name: "casting",
filename: "ExportedData.xls"
});
});
它解决了我的问题。
最好查看此数据表文档。在下面找到 URL 导出多行标题
我创建了一个自定义的 buttons.html5.js(基于 Ronnie 的解决方案),允许在 Excel 导出中使用多个页眉和页脚
https://gist.github.com/emersonmoretto/41993309f74a4b09f8e90c0a541de342
你好,我来晚了,但我通过 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>
“示例”(数据表 ID)
<a href="#" onclick="download_table_as_csv('example');">Download as CSV</a>
然后我调用了函数(只看上面的解决方案)
由于这是此问题的热门搜索结果,我想分享我的解决方法。
数据库导出功能将从最后一个标题行获取。 即使最后一行被隐藏,它也会这样做!
所以这个问题的一个非常简单的解决方案是在标题中再添加一行,给它你想要导出的列名,然后隐藏该行。
如:
<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: true 会完全破坏整个解决方案。哇,真是火车失事。
打印时使用按钮中的自定义功能。因为 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>
`);
}
使用extend 'excelHtml5',简单修改customizeData函数
customizeData函数中,有3个数组参数,header,body,fotter
默认操作是 header 参数取最后一个我们的表头, 如果我们的表有多个表头,那么我们用第一个表头替换表头参数,并将其余表头放入正文参数
extend: 'excelHtml5',
customizeData: function(data) {
var namatabel = "myTable";
var colLength = $("#" + namatabel + " thead:first tr:last th").length;
var jmlheader = $('#'+namatabel+' thead:first tr').length;
if (jmlheader > 1) {
data.body.unshift(data.header);
data.header=[""];
var j=0,rspan=[];
for(j=0;j<jmlheader;j++){
rspan[j]=[];
for(var i=0;i<colLength;i++){
rspan[j][i]=0;
}
}
var colSpan=0,rowSpan=0;
var topHeader = [],thisHead=[],thiscol=0,thisrow=0,jspan=0;
for(j=1;j<=(jmlheader-1);j++){
thisHead=[],thiscol=0;jspan=0;
$('#'+namatabel).find("thead:first>tr:nth-child("+j+")>th").each(function (index, element) {
colSpan = parseInt(element.getAttribute("colSpan"));
rowSpan = parseInt(element.getAttribute("rowSpan"));
jspan=jspan+colSpan;
if(rspan[thisrow][thiscol]>0){
for(var i=0;i<rspan[thisrow][thiscol];i++){
thisHead.push("");
}
}
if(rowSpan>1){
jspan=jspan-colSpan;
for (var i=thisrow+1; i < jmlheader; i++) {
rspan[i][jspan]=colSpan;
}
}
thisHead.push(element.innerHTML.toUpperCase());
for (var i = 0; i < colSpan - 1; i++) {
thisHead.push("");
}
thiscol++;
});
thisrow++;
if(j==1){
data.header=thisHead;
}else{
topHeader.push(thisHead);
}
};
thiscol=topHeader.length;
for(j=(thiscol-1);j>=0;j--){
data.body.unshift(topHeader[j]);
};
}
},
},
该代码也支持 rowspan 和 colspan