dcatadmin 添加导出csv文件功能
dcat-admin中纯PHP实现导出csv文件功能流程步骤
创建工具类
在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
{
// 获取grid所有筛选参数
$request = request()->all();
// 自动拼接生成URL参数字符串
$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');
// 打开PHP文件句柄,php://output 表示直接输出到浏览器
$fp = fopen('php://output', 'a');
// 计数器
$num = 0;
// 每次获取1000条数据写入
$chunkSize = 1000;
// 切片次数
$chunkNum = ceil($query->count() / $chunkSize);
// 输出Excel列名信息
$headings = [];
foreach (self::$exportTitles as $i => $v) {
//将utf-8编码转为gbk。理由是:Excel 以 ANSI 格式打开,不会做编码识别。如果直接用 Excel 打开 UTF-8 编码的 CSV 文件会导致汉字部分出现乱码。
$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) {
$num++;
// 刷新一下输出buffer,防止由于数据过多造成问题
if ($chunkSize == $num) {
ob_flush(); //清除内存
flush();
$num = 0;
}
$string = $value[$v];
// 处理科学计数,用不上可以删除
if (in_array($v, ['name', 'identity_card']))
$string = ("\t" . $value[$v]);
/**
* 处理状态显示,用不上可以删除
*
* 以下是模型代码示例,也可自行处理
*
* protected $appends = ['sex_desc'];
*
* public function getSexDescAttribute(): string
* {
* return Arr::get([1=>'男',2=>'女'], $this->attributes['sex'], '男');
* }
*
* 字段
* $this->attributes['sex']
* #
* $this->sex
*/
if (in_array($v, ['sex', 'status']))
$string = $value["{$v}_desc"];
// 转为gbk的时候可能会遇到特殊字符‘-’之类的会报错,加ignore表示这个特殊字符直接忽略不做转换。
$data[] = iconv("UTF-8", "GBK//IGNORE", $string);;
unset($v);
}
fputcsv($fp, $data);
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());
});
完
相关文章