Datatables服务端分页下Excel导出全部数据问题求助
解决Datatables服务端分页下Excel导出全部数据的问题
因为你启用了serverSide: true,前端设置modifier.page: 'all'不会自动让后端返回全部数据——服务端模式下所有数据的分页、筛选逻辑都由后端控制,前端的导出参数只是告诉Datatables要处理全部数据,但后端还是会按分页规则返回结果,所以必须前后端配合修改:
前端修改(两种可选方案)
方案1:临时调整分页参数后导出
修改Excel按钮的action函数,临时让Datatables请求全部数据,导出完成后恢复原有分页设置:
const table = new DataTable("#ajax-datatables-customers", { processing: true, serverSide: true, dom: "Brt<'row'<col-4 pt-2'l><'col-4 text-center'i><'col-4 text-center'p>>", serverMethod: 'post', buttons: [ { extend: 'excel', filename: 'hr_pivot_customers_' + new Date().toISOString().slice(0, 10), exportOptions: { columns: [0, 1, 2, 3, 4] }, action: function(e, dt, button, config) { // 保存原有分页条数 const originalLength = dt.settings()[0]._iDisplayLength; // 临时设置每页条数为-1,触发后端返回全部数据 dt.settings()[0]._iDisplayLength = -1; // 重新加载数据后执行导出,完成后恢复分页 dt.ajax.reload(function() { $.fn.dataTable.ext.buttons.excelHtml5.action(e, dt, button, config); dt.settings()[0]._iDisplayLength = originalLength; dt.ajax.reload(); }, false); } } ], ajax: { url :'<?php echo $_SERVER['PHP_SELF']; ?>?datatables', }, columns: [ { data: 'id'}, { data: null}, { data: 'email'}, { data: 'phone'}, { data: 'status'}, { data: 'status'} ], columnDefs : [ { targets:1, data: null, render: function (data, type, row) { var firstname = row.firstname; var lastname = row.lastname; if (firstname && lastname) { return firstname + ' ' + lastname; } else if (firstname) { return firstname; } else if (lastname) { return lastname; } else { return ''; } } } ], drawCallback : function( settings ) { } })
方案2:传递导出标记给后端
通过AJAX请求传递自定义参数,明确告知后端当前是导出请求:
// 定义全局标记变量 let isExporting = false; const table = new DataTable("#ajax-datatables-customers", { processing: true, serverSide: true, dom: "Brt<'row'<col-4 pt-2'l><'col-4 text-center'i><'col-4 text-center'p>>", serverMethod: 'post', buttons: [ { extend: 'excel', filename: 'hr_pivot_customers_' + new Date().toISOString().slice(0, 10), exportOptions: { columns: [0, 1, 2, 3, 4] }, action: function(e, dt, button, config) { isExporting = true; // 监听一次数据绘制完成事件,执行导出后恢复标记并刷新分页数据 dt.one('draw', function() { $.fn.dataTable.ext.buttons.excelHtml5.action(e, dt, button, config); isExporting = false; dt.ajax.reload(); }); dt.ajax.reload(); } } ], ajax: { url :'<?php echo $_SERVER['PHP_SELF']; ?>?datatables', data: function(d) { // 给请求添加导出标记参数 d.is_export = isExporting; } }, columns: [ { data: 'id'}, { data: null}, { data: 'email'}, { data: 'phone'}, { data: 'status'}, { data: 'status'} ], columnDefs : [ { targets:1, data: null, render: function (data, type, row) { var firstname = row.firstname; var lastname = row.lastname; if (firstname && lastname) { return firstname + ' ' + lastname; } else if (firstname) { return firstname; } else if (lastname) { return lastname; } else { return ''; } } } ], drawCallback : function( settings ) { } })
后端修改(PHP示例)
在处理Datatables请求的PHP代码中,根据前端传递的参数判断是否需要返回全部数据:
// 获取前端传递的导出标记 $isExport = isset($_POST['is_export']) && $_POST['is_export'] === true; // 查询总记录数(无论是否导出都需要) $totalSql = "SELECT COUNT(*) FROM customers"; $totalStmt = $pdo->query($totalSql); $totalRecords = $totalStmt->fetchColumn(); // 构建数据查询SQL $sql = "SELECT id, firstname, lastname, email, phone, status FROM customers"; // 非导出请求时添加分页限制 if (!$isExport) { $start = isset($_POST['start']) ? intval($_POST['start']) : 0; $length = isset($_POST['length']) ? intval($_POST['length']) : 10; $sql .= " LIMIT $start, $length"; } // 执行查询获取数据 $stmt = $pdo->query($sql); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); // 返回Datatables需要的JSON格式数据 $response = [ "draw" => intval($_POST['draw']), "recordsTotal" => $totalRecords, "recordsFiltered" => $totalRecords, // 导出时直接使用总条数 "data" => $data ]; echo json_encode($response);
这样修改后,点击Excel按钮时会请求全部数据导出,日常页面加载时依然保持分页逻辑,不会影响网站性能。
内容的提问来源于stack exchange,提问作者Sanju Nath
相关产品推荐
相关产品推荐

