微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决从 DataTables.js 导出所有行,同时仅显示其中一些行并保持分页

在数据表上,我需要:

  • 导出到 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 表中删除行将始终导致您所描述的问题:一页上的行太少。

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

一个解决方案

您可以通过使用 DataTables 过滤机制来避免此问题 - 但它有点尴尬,因为(如您在问题中所示)过滤行的方式取决于前一行中的数据。

这是一种方法:

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

  2. 导出到 Excel 时,您可以确保导出所有行(可见和隐藏) - 并确保不导出上面 (1) 中的额外隐藏列。

  3. 在“文档就绪”函数的末尾添加逻辑以计算显示/隐藏哪些行。这个逻辑基本上等同于你的问题。

代码:

$(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"
    }
  ]
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。