Laravel - 数据表从过滤后的数据中导出 excel

Laravel - Datatables export excel from filtered data

你好,我想从我的数据表中导出基于用户 filtered 数据的数据,例如:

我已经为所有行导出 excel 但现在我正在尝试导出基于 filtered 的数据,这是我在 function() 中过滤的数据index.blade php:

$(".filterButton").on('click', function(){
                        tableMediaOrder.column(8).search($('.input-advertiser-filter').val()).draw();
                        tableMediaOrder.column(7).search($('.input-agency-filter').val()).draw();
                        tableMediaOrder.column(9).search($('.input-brand-filter').val()).draw();
                    });

我曾尝试使用来自 Datatable example : Format Output Data 的格式化数据表示例,但我不知道如何放置导出按钮并将其作为自定义 <a href=""> 用于 Excel在上图中导出,也许有人可以提供一个如何制作的例子?谢谢!

编辑:

这是我在 index.blade 中的输入。php :

<div class="col">
            <button id="filterButton" class="btn btn-primary filterButton"><i class="fa fa-filter"></i> Filter</button>
            <div class="dropdown d-inline">

                <button class="btn btn-primary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
                    <i class="fa fa-file-excel-o"></i>  Export
                </button>
                <!-- dropdown-menu -->
                <div class="dropdown-menu" aria-labelledby="dropdownMenuButton" id="export-choose">
                    <a class="dropdown-item export-link" id="export-filtered">Excel</a>
                     <a class="dropdown-item export-link" href="{{ route('media-order.export') }}" id="exportRaw">Excel Raw</a>
                </div>
                <!-- end dropdown-menu -->
                    <button class="btn btn-primary float-right" data-toggle="modal" data-target="#addMediaOrderModal" data-backdrop="static" data-keyboard="false" class="btn btn-primary">
                            <i class="fa fa-plus-square mr-1"></i> Add Order
                        </button>
            </div><!-- dropdown -->
        </div>

到目前为止,我一直在尝试将 <a href="" id="export-filtered"> 用作 Export 按钮,将其添加为 onClick="exportFiltered" 函数并将其放入 javascript 但它不起作用,这是我的 javascript :

$(".exportFiltered").on('click', function(e) {
                $('.hiddenbuttons button').eq(0).click();
            });

但遗憾的是它不起作用,它只会使 Excel 导出变为空白

更新:数据Table

这是我的数据表:

'use strict';


        var addMediaOrderSubmitButton = Ladda('#addMediaOrderSubmitButton');
        var editMediaOrderSubmitButton = Ladda('#editMediaOrderSubmitButton');

        var tableMediaOrder = dt('#dt-media-order','media_order',{

            // dom: '<"hiddenbuttons"B>rtip',
            processing: true,
            serverside: true,
            iDisplayLength: 100,
            bFilter: true,
            searchable: true,
            exportOptions: {
                rows: 'visible'
            }, 

            ajax: {
                url: "{{ route('media-order.index') }}?dt=1",
                data: function (d){
                    d.filter_order = $('#input-order-filter').val();
                    d.filter_agency = $('#input-agency-filter').val();
                    d.filter_advertiser = $('#input-advertiser-filter').val();
                    d.filter_brand = $('#input-brand-filter').val();
                    // d.filter_start = $('#input-start-date').val();
                    // d.filter_end = $('#input-end-date').val();
                    //d.filterButton = $('#filterButton').val();
                },
            },

            columns: [
                    {
                    data: 'action', 
                    name: 'action',
                    orderable: false, 
                    sortable: false, 
                    className: 'text-center'},
                    {data: 'nomor', name: 'nomor'},
                    {data: 'nomor_reference', name: 'nomor_reference'},
                    {data: 'periode_start', 
                    name: 'periode_start',
                        render: function(data){
                            var date = new Date(data);
                            var month = date.getMonth() + 1;
                            return (month.toString().length > 1 ? month : "0" + month) + "/" + date.getDate() + "/" + date.getFullYear();
                        }
                    },
                    {
                        searchable: true, 
                        data: 'periode_end', 
                        name: 'periode_end',
                        render: function(date){
                            var date = new Date(date);
                            var month = date.getMonth() + 1;
                            return (month.toString().length > 1 ? month : "0" + month) + "/" + date.getDate() + "/" + date.getFullYear();
                        }
                    },
                    {
                        searchable: true, 
                        data: 'category_id', 
                        name: 'category_id',
                        render: function(data, type, row) {
                            switch (data) {
                                case '1':
                                    return 'New Order';
                                    break;
                                case '2':
                                    return 'Additional Order';
                                    break;
                                case '3':
                                    return 'Cancel Order';
                                    break;
                                case '4':
                                    return 'Paid';
                                    break;
                                case '5':
                                    return 'Bonus';
                                    break;

                                default:
                                    return 'Null';
                                    break;
                            }
                        }
                    },
                    {
                        searchable: true, 
                        data: 'type_id', 
                        name: 'type_id',
                        render: function(data, type, row) {
                            switch (data) {
                                case '1':
                                    return 'Reguler';
                                    break;
                                case '2':
                                    return 'Reguler PIB';
                                    break;
                                case '3':
                                    return 'CPRP';
                                    break;
                                case '4':
                                    return 'Package';
                                    break;
                                case '5':
                                    return 'Sponsor';
                                    break;
                                case '6':
                                    return 'Blocking';
                                    break;

                                default:
                                    return 'Null';
                                    break;
                            }
                        }
                    },
                    {
                        searchable: true, 
                        data: 'agency_name', 
                        name: 'agency_name' 
                    },
                    {
                        searchable: true, 
                        data: 'advertiser_name', 
                        name: 'advertiser_name' 
                    },
                    {
                        searchable: true, 
                        data: 'brand_name', 
                        name: 'brand_name' 
                    },
                    {
                        searchable: true, 
                        data: 'version_code', 
                        name: 'version_code' 
                    },
                    {
                        data: 'gross_value', 
                        name: 'gross_value' ,
                        render: $.fn.dataTable.render.number( ',', '.', 2, 'Rp','' )
                    },
                    {
                        data: 'nett_budget', 
                        name: 'nett_budget',
                        render: $.fn.dataTable.render.number( ',', '.', 2, 'Rp','' ) 
                    },
                    {
                        data: 'nett_cashback', 
                        name: 'nett_cashback',
                        render: $.fn.dataTable.render.number( ',', '.', 2, 'Rp','' ) 
                    },
                    {
                        data: 'nett_bundling', 
                        name: 'nett_bundling',
                        render: $.fn.dataTable.render.number( ',', '.', 2, 'Rp','' )
                    },
                    {data: 'spot', name: 'spot' },
                    {
                        searchable: true, 
                        data: 'accountexecutive_name', 
                        name: 'accountexecutive_name' 
                    },
                    {
                        searchable: true, 
                        data: 'userto_name', 
                        name: 'userto_name' 
                    },
                    {
                        searchable: true, 
                        data: 'group_id', 
                        name: 'group_id' 
                    },
                    {data: 'notes', name: 'notes' },
                    {
                        searchable: true, 
                        data: 'attachment_name', 
                        name: 'attachment_name' 
                    }
                ],
                buttons: [
                    { // this exports only filtered data
                      extend: 'excelHtml5',
                      exportOptions: {
                        modifier: { search: 'applied' }
                      }
                    }, 
                    { // this exports all data regardless of filtering
                      extend: 'excelHtml5',
                      exportOptions: {
                        modifier: { search: 'none' }
                      }
                    }
                ],

                initComplete: function(setting, json){
                    $('.hiddenbuttons').css('display','none');
                },

                rowCallback: function( row, data, index) {
                    if (data.isdisabled == 1){
                        $(row).css('background-color', 'rgba(255, 0, 0, 0.2)');
                    }
                }
        });

更新 2: 结果我忘了添加:

<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.3.1/js/dataTables.buttons.min.js"></script> 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.3.1/js/buttons.html5.min.js"></script>

还有一种自定义列的方法,因为“操作”列也像这样导出: 但遗憾的是,自定义导出 <a href="" id="export-filtered"> 仍然无法正常工作,再次感谢。

更新 3:

经过搜索和修改,我终于找到了我的解决方案,它正在使用:

var buttons = new $.fn.dataTable.Buttons(tableMediaOrder, {
             buttons: [
               {
                      extend: 'excelHtml5',

                      // "dom": {
                      //   "button": {
                      //       "tag": "button",
                      //       "className" : "exportFiltered",
                      //       }
                      //   },
                      
                      exportOptions: {
                        // rows: '"visible'
                        columns: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
                        modifier: { search: 'applied' }
                      }
                    }
            ]
        }).container().appendTo($('#exportFiltered'));

终于可以使用了:

<a href="#" class="dropdown-item" id="exportFiltered"></a>

作为外部 link 导出 excel。

您可以将 DataTables 导出按钮委托给另一个外部(非 DataTables)元素。

以下示例使用两个不同的 Excel 导出按钮 - 一个用于完全导出所有数据,而不考虑已应用的任何过滤,另一个用于仅导出过滤后的数据:

buttons: [ 
  // see https://datatables.net/reference/type/selector-modifier
  { // this exports only filtered data
    extend: 'excelHtml5',
    exportOptions: {
      modifier: { search: 'applied' }
    }
  }, 
  { // this exports all data regardless of filtering
    extend: 'excelHtml5',
    exportOptions: {
      modifier: { search: 'none' }
    }
  }
]

然后,我们使用以下方法隐藏这些按钮:

dom: '<"hiddenbuttons"B>rtip'

和:

initComplete: function(settings, json) {
  $('.hiddenbuttons').css('display', 'none');
}

现在可以从其他地方调用这两个 DataTables 导出按钮 - 例如,基于 select 列表的 change 事件。

这是 select 列表:

<select name="export" id="export">
    <option value="noexport">-- select --</option>
    <option value="filtered">Excel Filtered Data</option>
    <option value="alldata">Excel All Data</option>
</select>

这里是相关的事件侦听器:

$("#export").on('change', function(e) {
  var mode = $("#export :selected").val();
  if (mode === 'filtered') {
    $('.hiddenbuttons button').eq(0).click();
  } else if (mode === 'alldata') {
    $('.hiddenbuttons button').eq(1).click();
  }
});

作为参考,这里是完整的方法,作为一个独立的网页:

<!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">

  <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://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.html5.min.js"></script>

</head>

<body>

<div style="margin: 20px;">

    <input type="text" id="name" placeholder="Enter name">
    <input type="text" id="office" placeholder="Enter office">
    <button id="filterButton" type="button">Filter</button> 
    <select name="export" id="export">
        <option value="noexport">-- select --</option>
        <option value="filtered">Excel Filtered Data</option>
        <option value="alldata">Excel All Data</option>
    </select>

    <table id="example" class="display dataTable cell-border" style="width:100%">
    </table>

</div>

<script>

var dataSet = [
    {
      "id": "1",
      "name": "Tiger Nixon",
      "position": "System Architect",
      "salary": "0,800",
      "start_date": "2011/04/25",
      "office": "Zurich",
      "extn": "5421"
    },
    {
      "id": "2",
      "name": "Garrett Winters",
      "position": "Accountant",
      "salary": "0,750",
      "start_date": "2011/07/25",
      "office": "Tokyo",
      "extn": "8422"
    },
    {
      "id": "3",
      "name": "Ashton Cox",
      "position": "Junior Technical Author",
      "salary": ",000",
      "start_date": "2009/01/12",
      "office": "San Francisco",
      "extn": "1562"
    },
    {
      "id": "4",
      "name": "Cedric Kelly",
      "position": "Senior Javascript Developer",
      "salary": "3,060",
      "start_date": "2012/03/29",
      "office": "Edinburgh",
      "extn": "6224"
    },
    {
      "id": "5",
      "name": "Airi Satou",
      "position": "Accountant",
      "salary": "2,700",
      "start_date": "2008/11/28",
      "office": "Tokyo",
      "extn": "5407"
    },
    {
      "id": "6",
      "name": "Donna Snider",
      "position": "Customer Support",
      "salary": "2,000",
      "start_date": "2011/01/25",
      "office": "New York",
      "extn": "4226"
    }
  ];
 
$(document).ready(function() {

var table = $('#example').DataTable( {
  dom: '<"hiddenbuttons"B>rtip',
  lengthMenu: [ [5, -1], [5, "All"] ],
  data: dataSet,
  columns: [
    { title: "ID", data: "id" },
    { title: "Name", data: "name" },
    { title: "Office", data: "office" },
    { title: "Position", data: "position" },
    { title: "Start date", data: "start_date" },
    { title: "Extn.", data: "extn" },
    { title: "Salary", data: "salary" }
  ],
  buttons: [ 
    // see https://datatables.net/reference/type/selector-modifier
    { // this exports only filtered data
      extend: 'excelHtml5',
      exportOptions: {
        modifier: { search: 'applied' }
      }
    }, 
    { // this exports all data regardless of filtering
      extend: 'excelHtml5',
      exportOptions: {
        modifier: { search: 'none' }
      }
    }
  ],
  initComplete: function(settings, json) {
    $('.hiddenbuttons').css('display', 'none');
  }
} );

$("#filterButton").on('click', function() {
  table.column(1).search($('#name').val()).draw();
  table.column(2).search($('#office').val()).draw();
});

$("#export").on('change', function(e) {
  var mode = $("#export :selected").val();
  if (mode === 'filtered') {
    $('.hiddenbuttons button').eq(0).click();
  } else if (mode === 'alldata') {
    $('.hiddenbuttons button').eq(1).click();
  }
});



} );

</script>

</body>
</html>

更新

如果您想使用 <a> link 生成 Excel 导出,那么这可能会有所帮助:

假设我们有一个 link 就像您问题中的那个:

<a href="" id="export-filtered">Excel</a>

要为此处理点击事件,您可以使用以下方法:

$("#export-filtered").on('click', function(e) {
  e.preventDefault();
  $('.hiddenbuttons button').eq(0).click();
});

请注意 link 的 ID 是 export-filtered - 因此您需要在 JavaScript 中引用它,使用 # 符号(用于ID) - 而不是 . 符号(用于 class 名称):

$("#export-filtered")

那么您需要阻止应用默认的点击操作,因为您不希望点击导致您导航到另一个页面。即使您有 href="".

,我也建议您这样做

这对我有用,使用我的 DataTables 代码。

在您的问题中,您没有说明您是如何更改 DataTables 代码的 - 因此这可能仍然不适合您。如果是这样,那么我的示例和您的整体解决方案之间肯定存在其他差异(问题中未显示)。