2万条数据大概一分钟左右。适用纯数据导出
创建工具类
我是建在app/Admin/Extensions/Grid/Tools
下,可自行创建。
use Dcat\Admin\Grid\Tools\AbstractTool;
class UsersExporter extends AbstractTool
{
protected $title = '<i class="feather icon-download"></i> 导出';
protected $style = 'btn btn-success grid-refresh btn-mini users-exporter';
protected function script(): string
{
$request = request()->all();
$query = http_build_query($request, '&');
return <<<JS
$('.users-exporter').off('click').on('click', function() {
Dcat.confirm('数据过多时,请耐心等待', '确认导出?', function () {
window.location.href = '/admin/ajax/export/users?$query';
});
});
JS;
}
}
添加路由
在app/Admin/routes.php
文件种添加路由。
use App\Admin\Controllers\Ajax\ExportController;
Route::group([
'prefix' => config('admin.route.prefix'),
'namespace' => config('admin.route.namespace'),
'middleware' => config('admin.route.middleware'),
], function (Router $router) {
Route::get('ajax/export/users', [ExportController::class, 'users']);
});
创建ExportController类
use App\Http\Controllers\Controller;
use App\Models\Users;
use Illuminate\Support\Str;
set_time_limit(0);
ini_set('memory_limit', '5000M');
if (ob_get_contents()) ob_end_clean();
class ExportController extends Controller
{
public static array $exportTitles = [
'name' => '账号',
'username' => '昵称',
'email' => '邮箱',
'mobile' => '手机号',
'real_name' => '真实姓名',
'identity_card' => '身份证',
'area' => '身份证地址',
'sex' => '年龄',
'age' => '年龄',
'zodiac' => '生肖',
'status' => '状态',
'login_ip' => '登陆ip',
'login_at' => '登陆时间',
'created_at' => '创建时间',
'updated_at' => '更新时间'
];
public function users()
{
$fileName = '用户列表-' . (date('Ymd-His') . '-' . Str::random(6)) . '.csv';
$columns = array_keys(self::$exportTitles);
$query = Users::query()->select($columns)->where(function ($query) {
if (request('name'))
$query->where('name', request('name'));
if (request('mobile'))
$query->where('mobile', request('mobile'));
if (request('identity_card'))
$query->where('identity_card', request('identity_card'));
if (request('sex'))
$query->where('sex', request('sex'));
if (request('status'))
$query->where('status', request('status'));
});
if (isset($this->request['_sort']))
$query = $query->orderBy($this->request['_sort']['column'], $this->request['_sort']['type']);
else
$query = $query->orderByDesc('id');
header('content-Type:application/vnd.ms-excel;charset=utf-8');
header("Content-Disposition:attachment;filename=$fileName");
header('Cache-Control:max-age=0');
$fp = fopen('php://output', 'a');
$num = 0;
$chunkSize = 1000;
$chunkNum = ceil($query->count() / $chunkSize);
$headings = [];
foreach (self::$exportTitles as $i => $v) {
$headings[$i] = iconv("UTF-8", "GBK//IGNORE", $v);
unset($v);
}
fputcsv($fp, $headings);
for ($i = 0; $i < $chunkNum; $i++) {
$lists = $query->forPage(($i + 1), $chunkSize)->get();
foreach ($lists as $value) {
$data = [];
foreach ($columns as $v) {
$string = $value[$v];
if (in_array($v, ['name', 'identity_card']))
$string = ("\t" . $value[$v]);
if (in_array($v, ['sex', 'status']))
$string = $value["{$v}_desc"];
$data[] = iconv("UTF-8", "GBK//IGNORE", $string);;
unset($v);
}
fputcsv($fp, $data);
$num++;
if ($chunkSize == $num) {
ob_flush();
flush();
$num = 0;
}
unset($value, $data);
}
unset($lists);
}
ob_flush();
fclose($fp);
}
}
使用方法
use App\Admin\Extensions\Grid\Tools\UsersExporter;
$grid->tools(function (Grid\Tools $tools) {
$tools->append(new UsersExporter());
});