数据表删除导出为 pdf 的列和 excel
datatable remove column on export to pdf and excel
我在导出为 pdf 之前删除列时遇到问题,excel。
第二个问题是因为这个列的反向列不能正常工作
这是我使用的代码
$(document).ready(function(){
var arrayCol = new Array();
var table = $('#example').DataTable({
dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
initComplete:function ( ) {
var len = this.api().columns().count();
var array = Array.from(Array(len).keys());
arrayCol = array.reverse();
},
buttons: [
{
extend: 'pdf',
text: 'To PDF',
exportOptions: {
rows: function ( idx, data, node ) {
return data.reverse();
},
format: {
columns: ':visible:not(.not-export-col)',
header: function ( data, idx, node ) {
var headers = $('#example').DataTable().table().header();
var reversedHeaders = headers.innerText.split('\t').reverse();
return reversedHeaders[idx];
}
}
}
},
{
extend: 'excel',
text: 'exel',
exportOptions: {
columns: ':visible:not(.not-export-col)',
rows: function ( idx, data, node ) {
return data.reverse();
},
format: {
header: function ( data, idx, node ) {
var headers = $('#example').DataTable().table().header();
var reversedHeaders = headers.innerText.split('\t').reverse();
return reversedHeaders[idx];
}
}
}
}
]
});
});
和here是活生生的例子
您可以扩展使用 here 的方法来处理抑制一个或多个您不想导出的列的额外要求。
您对列选择器的使用效果很好:
columns: ':visible:not(.not-export-col)
要构建我们要导出的 headers 列表,可以使用 initComplete
函数(因此我们只执行一次此过程)。
我们还可以使用initComplete
函数来构建一个列索引数组,我们不想导出:
var ignorePositions = []; // column indexes of data NOT to be exported
var reversedHeaders = []; // with "not-export" headings removed
函数:
initComplete:function ( ) {
var thead = $( '#example' ).DataTable().table().header();
var tds = $( thead ).find( 'th' ).each(function( index ) {
if ( ! $( this ).hasClass('not-export-col') ) {
reversedHeaders.push( $( this ).text() );
} else {
ignorePositions.push(index);
}
});
reversedHeaders.reverse(); // to give us the export order we want
ignorePositions.reverse(); // reversed for when we splice() - see below
}
以上代码填充了两个数组:
reversedHeaders
- 包含我们将导出的那些列的标题列表(反向)。
ignorePositions
- 包含要忽略的列索引列表。在我们的示例中,唯一这样的列是最后一列(索引 6)。
然后我们可以在修改后的 exportOptions
代码中使用上述数组:
exportOptions: {
rows: function ( idx, data, node ) {
var keepRowData = [];
// we splice to remove those data fields we do not want to export:
ignorePositions.forEach(idx => data.splice(idx, 1) );
return data.reverse();
},
columns: ':visible:not(.not-export-col)',
format: {
header: function ( data, idx, node ) {
return reversedHeaders[idx];
}
}
}
唯一棘手的部分是需要使用 splice
直接更改原始 data
数组。这会从原始数据数组中删除每个不需要的元素,而不会创建新的数据数组。
综合起来:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
<!-- buttons -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.6.5/css/buttons.dataTables.min.css"/>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.colVis.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.flash.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.html5.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.print.min.js"></script>
</head>
<body>
<div class="container">
<table id="example" class="display nowrap" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
<th class="not-export-col">opr</th>
</tr>
</thead>
<!--
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
<th class="not-export-col">opr</th>
</tr>
</tfoot>
-->
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>,120</td>
<td><a href="www.google.com"><i class="wb-edit"></i></a></td>
</tr>
<!--
<tr>
<td>Garrett Winters</td>
<td>Director</td>
<td>Edinburgh</td>
<td>63</td>
<td>2011/07/25</td>
<td>,300</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td>,800</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012/03/29</td>
<td>,600</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
<tr>
<td>Jenna Elliott</td>
<td>Financial Controller</td>
<td>Edinburgh</td>
<td>33</td>
<td>2008/11/28</td>
<td>,300</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
<tr>
<td>Donna Snider</td>
<td>System Architect</td>
<td>New York</td>
<td>27</td>
<td>2011/01/25</td>
<td>,120</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
-->
</tbody>
</table>
</div>
<script>
$(document).ready(function() {
var ignorePositions = []; // column indexes of data NOT to be exported
var reversedHeaders = []; // with "not-export" headings removed
var table = $('#example').DataTable( {
dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
initComplete:function ( ) {
var thead = $( '#example' ).DataTable().table().header();
var tds = $( thead ).find( 'th' ).each(function( index ) {
if ( ! $( this ).hasClass('not-export-col') ) {
reversedHeaders.push( $( this ).text() );
} else {
ignorePositions.push(index);
}
});
reversedHeaders.reverse(); // to give us the export order we want
ignorePositions.reverse(); // reversed for when we splice() - see below
},
buttons: [
{
extend: 'pdf',
text: 'To PDF',
exportOptions: {
rows: function ( idx, data, node ) {
var keepRowData = [];
// we splice to remove those data fields we do not want to export:
ignorePositions.forEach(idx => data.splice(idx, 1) );
return data.reverse();
},
columns: ':visible:not(.not-export-col)',
format: {
header: function ( data, idx, node ) {
return reversedHeaders[idx];
}
}
}
}
]
} );
} );
</script>
</body>
</html>
像这样导出为 PDF:
最后的笔记:
我在上面的代码中只实现了PDF按钮。 Excel 按钮代码也需要添加,但应该相同。
我在代码中注释掉了 HTML table 的 <tfoot>
部分。我认为这意味着您还需要将 footer: function() { ... }
添加到您的实现中,以匹配 header: function() { ... }
代码。我假设如下(但我没有对此进行测试):
format: {
header: function ( data, idx, node ) {
return reversedHeaders[idx];
},
footer: function ( data, idx, node ) {
return reversedHeaders[idx];
}
}
更新
我看到烦人的警报。这是由于我的代码改变了数据行的长度(当它拼接出一个元素时)造成的。
第二个问题是,一旦一行被反转,它就会保持反转状态 - 因此,在下一次导出时,导出的数据顺序错误。
解决这两个问题很麻烦,我提出的解决方案是有限的:
我的解决方案假定您只想隐藏最后一列。
它还依赖于您能够检测行何时被反转 - 在我的例子中,这是通过检查行数据的最终位置中的特定值来完成的 - 同样,这不是一种非常可靠的方法 -但这是我现在唯一能想到的方法。
这是更新后的代码:
$(document).ready(function() {
var exportPositions = []; // column indexes of data NOT to be exported
var ignorePositions = []; // column indexes of data NOT to be exported
var reversedHeaders = []; // with "not-export" headings removed
var table = $('#example').DataTable( {
dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
initComplete:function ( ) {
var thead = $( '#example' ).DataTable().table().header();
var tds = $( thead ).find( 'th' ).each(function( index ) {
if ( ! $( this ).hasClass('not-export-col') ) {
reversedHeaders.push( $( this ).text() );
exportPositions.push(index);
} else {
ignorePositions.push(index);
}
});
reversedHeaders.reverse(); // to give us the export order we want
reversedHeaders.push('');
ignorePositions.reverse(); // reversed for when we splice() - see below
},
buttons: [
{
extend: 'pdf',
text: 'To PDF',
exportOptions: {
rows: function ( idx, data, node ) {
if (data[data.length - 1] === '~') {
data.reverse(); // un-reverse an already reversed record
data.push(data.splice(0, 1)[0]); // move first element to end of the array
}
// we splice to remove those data fields we do not want to export:
ignorePositions.forEach(idx => {
data.splice(idx, 1);
} );
data.reverse();
ignorePositions.forEach(idx => {
data.push('~'); // pad the array back to its original length
} );
return data;
},
columns: exportPositions, // here we use the array we built earlier
format: {
header: function ( data, idx, node ) {
return reversedHeaders[idx];
}
}
}
}
]
} );
} );
如果您的实际实施需要隐藏多列,那么这种方法可能不适合您。如果我对更强大的解决方案有任何想法,我会更新答案。
我在导出为 pdf 之前删除列时遇到问题,excel。 第二个问题是因为这个列的反向列不能正常工作 这是我使用的代码
$(document).ready(function(){
var arrayCol = new Array();
var table = $('#example').DataTable({
dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
initComplete:function ( ) {
var len = this.api().columns().count();
var array = Array.from(Array(len).keys());
arrayCol = array.reverse();
},
buttons: [
{
extend: 'pdf',
text: 'To PDF',
exportOptions: {
rows: function ( idx, data, node ) {
return data.reverse();
},
format: {
columns: ':visible:not(.not-export-col)',
header: function ( data, idx, node ) {
var headers = $('#example').DataTable().table().header();
var reversedHeaders = headers.innerText.split('\t').reverse();
return reversedHeaders[idx];
}
}
}
},
{
extend: 'excel',
text: 'exel',
exportOptions: {
columns: ':visible:not(.not-export-col)',
rows: function ( idx, data, node ) {
return data.reverse();
},
format: {
header: function ( data, idx, node ) {
var headers = $('#example').DataTable().table().header();
var reversedHeaders = headers.innerText.split('\t').reverse();
return reversedHeaders[idx];
}
}
}
}
]
});
});
和here是活生生的例子
您可以扩展使用 here 的方法来处理抑制一个或多个您不想导出的列的额外要求。
您对列选择器的使用效果很好:
columns: ':visible:not(.not-export-col)
要构建我们要导出的 headers 列表,可以使用 initComplete
函数(因此我们只执行一次此过程)。
我们还可以使用initComplete
函数来构建一个列索引数组,我们不想导出:
var ignorePositions = []; // column indexes of data NOT to be exported
var reversedHeaders = []; // with "not-export" headings removed
函数:
initComplete:function ( ) {
var thead = $( '#example' ).DataTable().table().header();
var tds = $( thead ).find( 'th' ).each(function( index ) {
if ( ! $( this ).hasClass('not-export-col') ) {
reversedHeaders.push( $( this ).text() );
} else {
ignorePositions.push(index);
}
});
reversedHeaders.reverse(); // to give us the export order we want
ignorePositions.reverse(); // reversed for when we splice() - see below
}
以上代码填充了两个数组:
reversedHeaders
- 包含我们将导出的那些列的标题列表(反向)。ignorePositions
- 包含要忽略的列索引列表。在我们的示例中,唯一这样的列是最后一列(索引 6)。
然后我们可以在修改后的 exportOptions
代码中使用上述数组:
exportOptions: {
rows: function ( idx, data, node ) {
var keepRowData = [];
// we splice to remove those data fields we do not want to export:
ignorePositions.forEach(idx => data.splice(idx, 1) );
return data.reverse();
},
columns: ':visible:not(.not-export-col)',
format: {
header: function ( data, idx, node ) {
return reversedHeaders[idx];
}
}
}
唯一棘手的部分是需要使用 splice
直接更改原始 data
数组。这会从原始数据数组中删除每个不需要的元素,而不会创建新的数据数组。
综合起来:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://cdn.datatables.net/1.10.22/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.22/css/jquery.dataTables.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
<!-- buttons -->
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.6.5/css/buttons.dataTables.min.css"/>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.colVis.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.flash.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.html5.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.6.5/js/buttons.print.min.js"></script>
</head>
<body>
<div class="container">
<table id="example" class="display nowrap" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
<th class="not-export-col">opr</th>
</tr>
</thead>
<!--
<tfoot>
<tr>
<th>Name</th>
<th>Position</th>
<th>Office</th>
<th>Age</th>
<th>Start date</th>
<th>Salary</th>
<th class="not-export-col">opr</th>
</tr>
</tfoot>
-->
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>System Architect</td>
<td>Edinburgh</td>
<td>61</td>
<td>2011/04/25</td>
<td>,120</td>
<td><a href="www.google.com"><i class="wb-edit"></i></a></td>
</tr>
<!--
<tr>
<td>Garrett Winters</td>
<td>Director</td>
<td>Edinburgh</td>
<td>63</td>
<td>2011/07/25</td>
<td>,300</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
<tr>
<td>Ashton Cox</td>
<td>Technical Author</td>
<td>San Francisco</td>
<td>66</td>
<td>2009/01/12</td>
<td>,800</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
<tr>
<td>Cedric Kelly</td>
<td>Javascript Developer</td>
<td>Edinburgh</td>
<td>22</td>
<td>2012/03/29</td>
<td>,600</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
<tr>
<td>Jenna Elliott</td>
<td>Financial Controller</td>
<td>Edinburgh</td>
<td>33</td>
<td>2008/11/28</td>
<td>,300</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
<tr>
<td>Donna Snider</td>
<td>System Architect</td>
<td>New York</td>
<td>27</td>
<td>2011/01/25</td>
<td>,120</td>
<td><a href="www.google.com"><span class="iconify" data-icon="fa:edit"></span></a></td>
</tr>
-->
</tbody>
</table>
</div>
<script>
$(document).ready(function() {
var ignorePositions = []; // column indexes of data NOT to be exported
var reversedHeaders = []; // with "not-export" headings removed
var table = $('#example').DataTable( {
dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
initComplete:function ( ) {
var thead = $( '#example' ).DataTable().table().header();
var tds = $( thead ).find( 'th' ).each(function( index ) {
if ( ! $( this ).hasClass('not-export-col') ) {
reversedHeaders.push( $( this ).text() );
} else {
ignorePositions.push(index);
}
});
reversedHeaders.reverse(); // to give us the export order we want
ignorePositions.reverse(); // reversed for when we splice() - see below
},
buttons: [
{
extend: 'pdf',
text: 'To PDF',
exportOptions: {
rows: function ( idx, data, node ) {
var keepRowData = [];
// we splice to remove those data fields we do not want to export:
ignorePositions.forEach(idx => data.splice(idx, 1) );
return data.reverse();
},
columns: ':visible:not(.not-export-col)',
format: {
header: function ( data, idx, node ) {
return reversedHeaders[idx];
}
}
}
}
]
} );
} );
</script>
</body>
</html>
像这样导出为 PDF:
最后的笔记:
我在上面的代码中只实现了PDF按钮。 Excel 按钮代码也需要添加,但应该相同。
我在代码中注释掉了 HTML table 的
<tfoot>
部分。我认为这意味着您还需要将footer: function() { ... }
添加到您的实现中,以匹配header: function() { ... }
代码。我假设如下(但我没有对此进行测试):
format: {
header: function ( data, idx, node ) {
return reversedHeaders[idx];
},
footer: function ( data, idx, node ) {
return reversedHeaders[idx];
}
}
更新
我看到烦人的警报。这是由于我的代码改变了数据行的长度(当它拼接出一个元素时)造成的。
第二个问题是,一旦一行被反转,它就会保持反转状态 - 因此,在下一次导出时,导出的数据顺序错误。
解决这两个问题很麻烦,我提出的解决方案是有限的:
我的解决方案假定您只想隐藏最后一列。
它还依赖于您能够检测行何时被反转 - 在我的例子中,这是通过检查行数据的最终位置中的特定值来完成的 - 同样,这不是一种非常可靠的方法 -但这是我现在唯一能想到的方法。
这是更新后的代码:
$(document).ready(function() {
var exportPositions = []; // column indexes of data NOT to be exported
var ignorePositions = []; // column indexes of data NOT to be exported
var reversedHeaders = []; // with "not-export" headings removed
var table = $('#example').DataTable( {
dom: 'B<"top"iflp<"clear">>rt<"bottom"ip<"clear">>',
initComplete:function ( ) {
var thead = $( '#example' ).DataTable().table().header();
var tds = $( thead ).find( 'th' ).each(function( index ) {
if ( ! $( this ).hasClass('not-export-col') ) {
reversedHeaders.push( $( this ).text() );
exportPositions.push(index);
} else {
ignorePositions.push(index);
}
});
reversedHeaders.reverse(); // to give us the export order we want
reversedHeaders.push('');
ignorePositions.reverse(); // reversed for when we splice() - see below
},
buttons: [
{
extend: 'pdf',
text: 'To PDF',
exportOptions: {
rows: function ( idx, data, node ) {
if (data[data.length - 1] === '~') {
data.reverse(); // un-reverse an already reversed record
data.push(data.splice(0, 1)[0]); // move first element to end of the array
}
// we splice to remove those data fields we do not want to export:
ignorePositions.forEach(idx => {
data.splice(idx, 1);
} );
data.reverse();
ignorePositions.forEach(idx => {
data.push('~'); // pad the array back to its original length
} );
return data;
},
columns: exportPositions, // here we use the array we built earlier
format: {
header: function ( data, idx, node ) {
return reversedHeaders[idx];
}
}
}
}
]
} );
} );
如果您的实际实施需要隐藏多列,那么这种方法可能不适合您。如果我对更强大的解决方案有任何想法,我会更新答案。