[Laravel-Excel中文文档] 使用queued队列实现后端分批次导出大量数据
如上所说我们希望所有Laraveld队列导出数据;接下来我们先看实际使用Demo再看文档。
实战使用Demo
asda
官方文档翻译
如果您正在处理大量数据,使用queue队列处理进程可能更明智。
我们提供以下导出类:
namespace App\Exports;
use App\Invoice;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
class InvoicesExport implements FromQuery
{
use Exportable;
public function query()
{
return Invoice::query();
}
}
现在调用->queue()
就可以简单实现队列方法。
(new InvoicesExport)->queue(invoices.xlsx);
return back()->withSuccess(Export started!);
在队列中将会使用chunck分块查询并且将多个jobs链接起来。这些job将以正确的顺序执行,并且只有在之前的作业都没有失败的情况下才会执行。
隐式导出队列
您还可以将导出隐式标记为排队导出。你可以使用 Laravel 的ShouldQueue
协议来实现。
namespace App\Exports;
use App\Invoice;
use Illuminate\Contracts\Queue\ShouldQueue;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
class InvoicesExport implements FromQuery, ShouldQueue
{
use Exportable;
public function query()
{
return Invoice::query();
}
}
在您的控制器中,您现在可以调用普通->store()
方法。根据ShouldQueue
协议的存在,导出将排队执行。
(new InvoicesExport)->store(invoices.xlsx);
追加jobs
该queue()
方法返回 Laravel 的PendingDispatch
. 这意味着您可以链接额外的jobs,这些job将被添加到队列的末尾,并且只有在所有导出作业都正确执行时才执行。
比如您想要在Excel文件导出生成后,发送邮件通知客户可以尝试使用这种方法。
(new InvoicesExport)->queue(invoices.xlsx)->chain([
new NotifyUserOfCompletedExport(request()->user()),
]);
namespace App\Jobs;
use App\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\SerializesModels;
class NotifyUserOfCompletedExport implements ShouldQueue
{
use Queueable, SerializesModels;
public $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function handle()
{
$this->user->notify(new ExportReady());
}
}
处理queued导出中的失败
在对导出进行排队时,您可能需要一种处理失败导出的方法。您可以在您的导出类添加failed
方法来实现。
use Throwable;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\WithHeadings;
class UsersExport implements FromQuery, WithHeadings
{
public function failed(Throwable $exception): void
{
// handle failed export
}
}
自定义队列
因为PendingDispatch
是返回的,所以我们也可以改变应该使用的队列。
对于 Laravel 8+:
(new InvoicesExport)->queue(invoices.xlsx)->onQueue(exports);
对于旧版本的 Laravel:
(new InvoicesExport)->queue(invoices.xlsx)->allOnQueue(exports);
多服务器设置
如果您正在处理多服务器设置(例如使用负载平衡器),您可能希望确保用于存储每个数据块的临时文件对于每个作业都是相同的。您可以通过在 config.xml 中配置远程临时文件来实现此目的。
在config/excel.php
temporary_files => [
remote_disk => s3,
],
Job中间件
如果您使用的是 Laravel 6,作业中间件 (打开新窗口)可以使用以下middleware
方法附加到导出类:
namespace App\Exports;
use App\Jobs\Middleware\RateLimited;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromQuery;
class ExportClass implements FromQuery
{
use Exportable;
public function middleware()
{
return [new RateLimited];
}
public function query()
{
// ...
}
}
本地化排队导出
如果你想本地化你的队列导出,你应该HasLocalePreference
在你的导出上实现协议:
namespace App\Exports;
use Illuminate\Contracts\Translation\HasLocalePreference;
use Maatwebsite\Excel\Concerns\Exportable;
class ExportClass implements HasLocalePreference
{
use Exportable;
public function __construct(string $locale)
{
$this->locale = $locale;
}
public function preferredLocale()
{
return $this->locale;
}
}
自定义查询大小
排队的可导出文件以块的形式处理;每个块都是由QueuedWriter
. 对于实现FromQuery问题的可导出文件,作业数是通过除以$query->count()
块大小来计算的。
何时使用
根据query()
方法的实现(例如使用groupBy
子句时),前面提到的计算可能不正确。
如果是这种情况,您应该使用WithCustomQuerySize
关注点来提供查询大小的自定义计算。
更多相关好文
-
laravel中distinct()的使用方法与去重 2017-09-11
-
Laravel将view缓存为静态html,laravel页面静态缓存 2021-10-09
-
[ laravel爬虫实战--基础篇 ] guzzle描述与安装 2017-11-01
-
[ 配置教程 ] 在ubuntu16.04中部署LNMP环境(php7+maridb且开启maridb远程以及nginx多域名访问 )并配置laravel环境 2017-07-18
-
mysql如何给运营人员添加只有查询权限的账号 2024-12-02
热门文章
-
mysql如何给运营人员添加只有查询权限的账号 2024-12-02
-
Mac 安装mysql并且配置密码 2024-11-20
-
阿里云不同账号(跨账号)ECS服务器同地域如何实现免费内网互通? 2024-11-12
-
electron安装使用better-sqlite3并解决NODE_MODULE_VERSION xxx. This version of Node.js requires 2024-11-06
-
Zerotier+Moon+Nginx实现内网穿透搭建网站 2024-08-23
Ubuntu 22.04系统编译安装Nginx1.22教程