Skip to content

数据导出

CatchAdmin 专业版提供四种常用导出方式:

场景建议方案入口
常规列表导出标准导出类Catch\Support\Excel\Export
导出到本地文件标准导出类或集合宏export()
大数据量导出xlswriterCatch\Support\Excel\XlsWriterExport
超大数据量流式导出CSV 流式导出downloadAsCsv()

标准导出类

标准导出类适合大部分后台列表导出。数据量在几千到两万条以内时,优先使用这一套。

php
<?php

declare(strict_types=1);

namespace Modules\User\Export;

use Catch\Support\Excel\Export;
use Modules\User\Models\User;

class UserExport extends Export
{
    protected array $header = [
        'ID' => 10,
        '昵称' => 20,
        '邮箱' => 30,
        '创建时间' => 24,
    ];

    public function array(): array
    {
        return User::query()
            ->when($this->params['username'] ?? null, fn ($query, $username) => $query->where('username', 'like', "%{$username}%"))
            ->get(['id', 'username', 'email', 'created_at'])
            ->toArray();
    }
}

控制器里直接注入导出类:

php
public function export(Request $request, UserExport $export): mixed
{
    return $export->setParams($request->all())->download();
}

常用 API

方法 / 属性说明
array(): array必填,返回导出数据
$header表头。['标题1', '标题2']['标题1' => 12, '标题2' => 20]
download(?string $filename = null)直接下载
export(?string $disk = null)保存到文件,返回文件路径
setParams(array $params)传入查询参数
setFilename(string $filename)自定义文件名
setPath(string $path)自定义保存目录
$toCsvLimit超过阈值后自动按 CSV 导出,默认 20000

保存到文件

php
public function exportToFile(Request $request, UserExport $export): string
{
    return $export
        ->setParams($request->all())
        ->setFilename('users.xlsx')
        ->export();
}

Collection 快捷导出

导出逻辑很简单时,直接使用集合宏更省事。

php
public function export(): mixed
{
    return User::query()
        ->get(['id', 'username', 'email', 'created_at'])
        ->download(
            ['ID', '昵称', '邮箱', '创建时间'],
            ['id', 'username', 'email', 'created_at']
        );
}

支持的快捷方法:

方法说明
download(array $header, array $fields = [])直接下载
export(array $header)保存到文件
lazyExport(array $header, array $fields = [], bool $useXlsWriter = false)导出到文件,第三个参数支持切换到 xlswriter

大数据量导出

大数据量导出推荐使用 Catch\Support\Excel\XlsWriterExport。这一套适合低内存导出和异步导出。

php
<?php

declare(strict_types=1);

namespace Modules\User\Export;

use Catch\Support\Excel\XlsWriterExport;
use Illuminate\Support\LazyCollection;
use Modules\User\Models\User;

class UserXlsWriterExport extends XlsWriterExport
{
    protected array $header = [
        'id' => ['title' => 'ID'],
        'username' => ['title' => '昵称'],
        'email' => ['title' => '邮箱'],
        'created_at' => ['title' => '创建时间'],
    ];

    public function array(): array|LazyCollection
    {
        return User::query()
            ->select('id', 'username', 'email', 'created_at')
            ->cursor();
    }

    public function mapRow(array $row): array
    {
        $row['created_at'] = (string) $row['created_at'];

        return $row;
    }
}

控制器:

php
public function exportLarge(Request $request, UserXlsWriterExport $export): mixed
{
    return $export->setParams($request->all())->download();
}

xlswriter 常用 API

方法说明
`array(): arrayLazyCollection`
mapRow(array $row)单行映射
setFilename(string $filename)自定义文件名
setPath(string $path)自定义保存目录
setConfig(array $config)设置 xlswriter 配置
disableConstMemory()关闭常量内存模式
unlimitedMemory()放开 PHP 内存限制
formats()设置样式
password()设置编辑保护密码

LazyCollection 快捷导出

LazyCollection 已经扩展了高性能导出方法:

php
public function exportLarge(): mixed
{
    return User::query()
        ->select('id', 'username', 'email', 'created_at')
        ->cursor()
        ->lazyDownload(['ID', '昵称', '邮箱', '创建时间']);
}

CSV 流式导出

CSV 是最稳的超大数据量方案。适合几十万到百万级导出。

php
public function exportCsv(): mixed
{
    return User::query()
        ->select('id', 'username', 'email', 'created_at')
        ->cursor()
        ->downloadAsCsv(['ID', '昵称', '邮箱', '创建时间'], 'users.csv');
}

需要自定义编码、分隔符或行格式时,可以直接使用 Catch\Support\Excel\Csv

php
use Catch\Support\Excel\Csv;

public function exportCsv(): mixed
{
    return (new Csv())
        ->header(['ID', '昵称', '邮箱'])
        ->setOutputEncoding('GBK')
        ->setFields(['id', 'username', 'email'])
        ->download(
            'users.csv',
            User::query()->select('id', 'username', 'email')->cursor()
        );
}

异步导出

导出耗时较长时,直接接入异步任务。

php
<?php

declare(strict_types=1);

namespace Modules\User\Export;

use Catch\Contracts\AsyncTaskInterface;
use Catch\Support\Excel\Export;
use Modules\System\Support\Traits\AsyncTaskDispatch;

class UserExport extends Export implements AsyncTaskInterface
{
    use AsyncTaskDispatch;

    protected array $header = ['ID', '昵称', '邮箱', '创建时间'];

    public function array(): array
    {
        return \Modules\User\Models\User::query()
            ->get(['id', 'username', 'email', 'created_at'])
            ->toArray();
    }
}

控制器里推送任务:

php
public function export(Request $request, UserExport $export): mixed
{
    return $export->setParams($request->all())->push();
}

异步任务配置和调度方式见 异步任务

前端接入

CatchTable 最常见的写法如下:

vue
<catch-table
  api="users"
  :columns="columns"
  :exports="true"
  exportUrl="/user/export"
  importUrl="/user/import"
/>
  • exports 控制导出按钮显示
  • exportUrl 指定导出接口
  • importUrl 指定导入接口

adminResource 会自动注册 export 路由,详细规则见 路由扩展

注意事项

  • 表头顺序要和 array() 返回的数据顺序一致
  • 导出筛选条件需要通过 setParams() 传入
  • 数据量超过 20000 时,标准导出类会自动切换到 CSV
  • 百万级导出优先使用 xlswriter 或 CSV
  • xlswriter 方案依赖 PHP xlswriter 扩展