从datatable .js导出所有行,同时只显示其中的一些并保持分页



对于一个DataTable,我需要:

  • 导出到Excel的所有行
  • 根据ItemId列的值,只在屏幕上显示一些行
  • 使用30VISIBLE保持分页效率每页行数

要在屏幕上仅显示所需的行,我使用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个可见行,这不是我想要的。但是,应该隐藏的行确实被隐藏了,并且Export工作得很好,因为它导出了所有行。这里的问题是分页
  • 如果我删除drawCallback,所有的行都显示在屏幕上,这不是我想要的。导出(显然)工作得很好,因为所有行都被显示和导出。这里的问题是显示的行

如何保持30可见导出所有其中(可见+隐藏)?

为了记录,我使用的是DataTables 1.10.21

问题

我认为以问题中所示的方式从HTML表中删除行总是会导致你所描述的问题:一页上的行太少。

这是因为您已经从HTML表(DOM)中删除了数据,但DataTables(存储所有数据的JavaScript对象)对这些更改一无所知。所以,它认为你有一整页的数据,显示30条记录。

一个解

您可以通过使用datattables过滤机制来避免这个问题—但是这有点尴尬,因为(正如您在问题中所显示的)您如何过滤一行取决于前一行中的数据。

这里有一个方法:

  1. 在表中创建一个隐藏列,并用一个特定的文本值填充该列,该文本值指示是否应该显示一行。

  2. 当导出到Excel时,这是你确保所有行(可见和隐藏)被导出的地方-并且你确保我们的额外隐藏列,从上面(1),不被导出。

  3. 在"document ready"结尾添加逻辑函数来计算显示/隐藏哪些行。这个逻辑基本上相当于你问题中的逻辑。

代码:

$(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": "$320,800",
"start_date": "2011/04/25",
"office": "Edinburgh",
"extn": "5421"
},
... // and so on...
{
"id": "2",
"name": "Garrett Winters",
"position": "Accountant",
"salary": "$170,750",
"start_date": "2011/07/25",
"office": "Tokyo",
"extn": "8422"
}
]
};

最新更新