导出 ajax/服务器端数据表的最佳方式

Posted

技术标签:

【中文标题】导出 ajax/服务器端数据表的最佳方式【英文标题】:Best way to export ajax/serverside datatable 【发布时间】:2016-10-30 06:52:00 【问题描述】:

对于我的应用程序,我有一个使用 ajax 检索记录的数据表。数据表允许用户排序​​、搜索,我添加了一个额外的自定义字段,允许用户根据类别进行过滤。

现在,当我使用 datatables 提供的 html5 方法导出到 CSV/Excel 时,我在导出中只得到浏览器中显示的记录。因此,我唯一的选择是进行服务器端导出。我有一个有效的导出功能,但我正在努力寻找正确的方法将我的过滤器也传递给这个导出功能。

我不确定将参数导入模型中的导出方法的最佳方法是什么。我考虑过包括 jQuery 以将参数添加到我的 link_to,但我不确定如何执行此操作,以及这是否被认为是“好的做法”。

我的代码:

表格

<%= link_to "Download CSV", vendor_skus_path(format: "csv") %>

<%= select_tag "vendor-select", options_from_collection_for_select(@vendors, "id", "name"), include_blank: true, class:"vendor-select form-control" %>   

<table id="vendor-skus-table" class="table table-striped table-bordered table-hover" data-source="<%= vendor_skus_path(format: :json) %>">
  <thead>
    <tr>
      <th>Name</th>
      <th>Vendor</th>
      <th>Inventory Quantity</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

$('#vendor-select.vendor-select').on('change', function() 
  $('#vendor-skus-table').DataTable().ajax.reload();
);

咖啡脚本

$ ->
  $('#vendor-skus-table').DataTable
    processing: true
    serverSide: true
    retrieve: true
    pagingType: 'full_numbers'
    ajax: data: (d) ->
      d.sku = $('#vendor-skus-table').data('source')
      d.vendor_id = $('#vendor-select').val();
      return

数据表

class VendorSkuDatatable < AjaxDatatablesRails::Base
  def_delegators :@view, :params, :link_to, :vendor_skus_path, :vendor_path

  def sortable_columns
    @sortable_columns ||= ['VendorSku.name', 'Vendor.name', 'VendorSku.inventory_quantity' ]
  end

  def searchable_columns
    @searchable_columns ||= ['VendorSku.name', 'Vendor.name']
  end

  private

  def data
    records.map do |record|
      [
        link_to(record.name, record),
        link_to(record.vendor.name, record.vendor),
        record.inventory_quantity
      ]
    end
  end

  def get_raw_records
    # insert query here
    if params[:vendor_id].present?
      VendorSku.joins(:vendor).where(vendor_id: params[:vendor_id])
    else
      VendorSku.joins(:vendor).all
    end
  end
end

控制器动作

def index
  @vendor_skus = VendorSku.order(:name)
  @vendor_sku = VendorSku.new
  @vendors = Vendor.all

  respond_to do |format|
    format.html
    format.csv  send_data @vendor_skus.to_csv 
    format.json  render json: VendorSkuDatatable.new(view_context,  vendor_id: params[:vendor_id] ) 
    format.xls #  send_data @vendor_skus.to_csv(col_sep: "\t")  
  end    
end

模型方法

def self.to_csv(options = )
  CSV.generate(options) do |csv|
    csv << column_names
    all.each do |product|
      csv << product.attributes.values_at(*column_names)
    end
  end
end

【问题讨论】:

【参考方案1】:

如果您还没有致力于编写自定义服务器端导出的想法,您可以简单地添加length menu。您提到当您使用导出按钮时,它仅导出可见行,但您是否尝试过允许用户在导出前更改可见行数?这似乎是一个更简单的解决方案,因为听起来您首先想使用导出按钮。

$('#example').dataTable( 
    "lengthMenu": [ [10, 25, 50, -1], [10, 25, 50, "All"] ]
 );

上面的代码块将提供 4 个选项来显示记录数; 10、25、50 和所有记录。您可以添加或删除您想要的任何分页选项,但在我看来,如果您至少拥有每个数组的 [-1]["All"] 部分,您可以允许用户在导出之前显示所有记录以将它们全部放入excel文件。您甚至可以更改 excel 导出确认窗口,让用户知道在导出之前执行此操作。

【讨论】:

以上是关于导出 ajax/服务器端数据表的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

Ajax+Node.js前后端交互最佳入门实践(05)

Ajax+Node.js前后端交互最佳入门实践(07)

重型 AJAX Java 应用程序的最佳服务器端框架

前后端分离,最佳实践

Ajax+Node.js前后端交互最佳入门实践(01)

Ajax+Node.js前后端交互最佳入门实践(01)