从 DataTables.js 导出所有行,同时只显示其中的一些并保持分页
Export ALL rows from DataTables.js while displaying only some of them and keeping the pagination
在 DataTable 上,我需要:
- 导出到 Excel 所有行
- 根据 ItemId 列的值在屏幕上仅显示部分行
- 保持分页高效,每页 30 VISIBLE 行
为了在屏幕上只显示所需的行,我使用 drawCallback
// Each row has an ItemId property. Several rows may have the same ItemId
// I want to display only the first row for each ItemId, but export all rows
drawCallback: function (settings) {
var api = this.api();
var ids = [];
$.each(api.rows({ page: 'current' }).data(), function (i, v) {
if ($.inArray(v.ItemId, ids) != -1)
$("#myDatatable tbody tr:eq(" + i + ")").css("visibility", "collapse")
else
ids.push(v.ItemId);
})
},
但是,我正在使用分页系统,我想每页显示 30 可见 行。
- 如果我使用上面的
drawCallback
,我每页只有 1 或 2 行可见,这不是我想要的。但是,应该隐藏的行确实被隐藏了,并且导出效果很好,因为它导出了所有行。这里的问题是分页
- 如果我删除
drawCallback
,所有行都显示在屏幕上,这也不是我想要的。导出工作(显然)以及显示和导出所有行。这里的问题是显示的行
如何在屏幕上保留 30 可见 行,同时导出所有行(可见+隐藏)?
郑重声明,我使用的是 DataTables 1.10.21
问题
我认为按照问题中显示的方式从 HTML table 中删除行总是会导致您描述的问题:一页上的行太少。
这是因为您已从 HTML table(DOM)中删除了数据,但删除了 DataTables(存储所有数据的 JavaScript 对象)对这些变化一无所知。因此,它认为您有整页数据,显示 30 条记录。
一个解决方案
您可以通过使用 DataTables 过滤机制来避免这个问题 - 但它有点笨拙,因为(如您在问题中所示)如何过滤行取决于前几行中的数据。
这是一种方法:
在 table 中创建一个隐藏列,并用指示是否应显示某行的特定文本值填充该列。
当导出到 Excel 时,您可以确保所有行(可见和隐藏)都被导出 - 并且您可以确保我们的额外隐藏列(来自上面的 (1))是未导出。
在“文档就绪”函数的末尾添加逻辑以计算哪些行是shown/hidden。这个逻辑基本上等同于你的问题。
代码:
$(document).ready(function() {
var firstFound = "##first_occurrence##"; // needs to be unique - must not clash with other data in the table
var table = $('#myDatatable').DataTable( {
data: dataSet.data, // my test data is sourced from a JavaScript variable (see below)
pageLength: 5, // just for testing
columns: [
{ title: "Name", data: "name" },
{ title: "Office", data: "office" },
{ title: "Position", data: "position" }, // this is my equivalent of your ItemId column
{ title: "Start date", data: "start_date" },
{ title: "Salary", data: "salary" },
{ data: "id", visible: false } // this is where the 'firstFound' value is placed
],
search: {
search: firstFound // forces filtering to be applied
},
dom: 'Brtip',
buttons: [
{
title: '',
extend: 'excel',
text: 'To Excel',
exportOptions: {
rows: { order:'current', search: 'none' }, // export all rows
columns: [ 0, 1, 2, 3, 4 ] // export all columns apart from the final column in my table
}
}
]
} );
// the logic to populate the hidden column in my table:
var positions = [];
// column index 5 is the hidden column, used for filtering.
// column index 2 is my "job position" data (accountant, etc).
table.rows().every( function (rowIdx, tableLoop, rowLoop) {
var filterCell = table.cell( { row: rowIdx, column: 5 } );
var position = table.cell( { row: rowIdx, column: 2 } ).data();
if ($.inArray(position, positions) === -1) {
filterCell.data(firstFound);
positions.push(position);
} else {
filterCell.data("");
}
} );
// finally, re-draw the table to ensure the data changes are applied:
table.draw();
} );
这向您展示了一种方法。它可能不是您所需要的。例如,我特意隐藏了全局过滤框。一旦数据被过滤和显示,您就不能以其他方式重新过滤它。
作为参考,我的示例测试数据如下所示:
var dataSet = {
"data": [
{
"id": "1",
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "0,800",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": "5421"
},
... // and so on...
{
"id": "2",
"name": "Garrett Winters",
"position": "Accountant",
"salary": "0,750",
"start_date": "2011/07/25",
"office": "Tokyo",
"extn": "8422"
}
]
};
在 DataTable 上,我需要:
- 导出到 Excel 所有行
- 根据 ItemId 列的值在屏幕上仅显示部分行
- 保持分页高效,每页 30 VISIBLE 行
为了在屏幕上只显示所需的行,我使用 drawCallback
// Each row has an ItemId property. Several rows may have the same ItemId
// I want to display only the first row for each ItemId, but export all rows
drawCallback: function (settings) {
var api = this.api();
var ids = [];
$.each(api.rows({ page: 'current' }).data(), function (i, v) {
if ($.inArray(v.ItemId, ids) != -1)
$("#myDatatable tbody tr:eq(" + i + ")").css("visibility", "collapse")
else
ids.push(v.ItemId);
})
},
但是,我正在使用分页系统,我想每页显示 30 可见 行。
- 如果我使用上面的
drawCallback
,我每页只有 1 或 2 行可见,这不是我想要的。但是,应该隐藏的行确实被隐藏了,并且导出效果很好,因为它导出了所有行。这里的问题是分页 - 如果我删除
drawCallback
,所有行都显示在屏幕上,这也不是我想要的。导出工作(显然)以及显示和导出所有行。这里的问题是显示的行
如何在屏幕上保留 30 可见 行,同时导出所有行(可见+隐藏)?
郑重声明,我使用的是 DataTables 1.10.21
问题
我认为按照问题中显示的方式从 HTML table 中删除行总是会导致您描述的问题:一页上的行太少。
这是因为您已从 HTML table(DOM)中删除了数据,但删除了 DataTables(存储所有数据的 JavaScript 对象)对这些变化一无所知。因此,它认为您有整页数据,显示 30 条记录。
一个解决方案
您可以通过使用 DataTables 过滤机制来避免这个问题 - 但它有点笨拙,因为(如您在问题中所示)如何过滤行取决于前几行中的数据。
这是一种方法:
在 table 中创建一个隐藏列,并用指示是否应显示某行的特定文本值填充该列。
当导出到 Excel 时,您可以确保所有行(可见和隐藏)都被导出 - 并且您可以确保我们的额外隐藏列(来自上面的 (1))是未导出。
在“文档就绪”函数的末尾添加逻辑以计算哪些行是shown/hidden。这个逻辑基本上等同于你的问题。
代码:
$(document).ready(function() {
var firstFound = "##first_occurrence##"; // needs to be unique - must not clash with other data in the table
var table = $('#myDatatable').DataTable( {
data: dataSet.data, // my test data is sourced from a JavaScript variable (see below)
pageLength: 5, // just for testing
columns: [
{ title: "Name", data: "name" },
{ title: "Office", data: "office" },
{ title: "Position", data: "position" }, // this is my equivalent of your ItemId column
{ title: "Start date", data: "start_date" },
{ title: "Salary", data: "salary" },
{ data: "id", visible: false } // this is where the 'firstFound' value is placed
],
search: {
search: firstFound // forces filtering to be applied
},
dom: 'Brtip',
buttons: [
{
title: '',
extend: 'excel',
text: 'To Excel',
exportOptions: {
rows: { order:'current', search: 'none' }, // export all rows
columns: [ 0, 1, 2, 3, 4 ] // export all columns apart from the final column in my table
}
}
]
} );
// the logic to populate the hidden column in my table:
var positions = [];
// column index 5 is the hidden column, used for filtering.
// column index 2 is my "job position" data (accountant, etc).
table.rows().every( function (rowIdx, tableLoop, rowLoop) {
var filterCell = table.cell( { row: rowIdx, column: 5 } );
var position = table.cell( { row: rowIdx, column: 2 } ).data();
if ($.inArray(position, positions) === -1) {
filterCell.data(firstFound);
positions.push(position);
} else {
filterCell.data("");
}
} );
// finally, re-draw the table to ensure the data changes are applied:
table.draw();
} );
这向您展示了一种方法。它可能不是您所需要的。例如,我特意隐藏了全局过滤框。一旦数据被过滤和显示,您就不能以其他方式重新过滤它。
作为参考,我的示例测试数据如下所示:
var dataSet = {
"data": [
{
"id": "1",
"name": "Tiger Nixon",
"position": "System Architect",
"salary": "0,800",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": "5421"
},
... // and so on...
{
"id": "2",
"name": "Garrett Winters",
"position": "Accountant",
"salary": "0,750",
"start_date": "2011/07/25",
"office": "Tokyo",
"extn": "8422"
}
]
};