佇列任務
GeneratePdfJob 提供開箱即用的佇列式 PDF 產生功能。對於耗時的文件,將工作交給背景工作者可以避免阻塞 HTTP 請求。
php
use Yeeefang\TcpdfNext\Laravel\Jobs\GeneratePdfJob;派發任務
建立任務時傳入一個閉包,該閉包接收 Document 實例並定義 PDF 的內容:
php
use Yeeefang\TcpdfNext\Laravel\Jobs\GeneratePdfJob;
GeneratePdfJob::dispatch(
builder: function ($pdf) use ($report) {
$pdf->setTitle($report->title)
->addPage()
->setFont('Helvetica', 'B', 16)
->cell(0, 10, $report->title)
->setFont('Helvetica', '', 11)
->multiCell(0, 6, $report->body);
},
outputPath: storage_path("app/reports/{$report->id}.pdf"),
);成功與失敗回呼
透過 onSuccess 和 onFailure 回呼處理任務完成後的邏輯:
php
GeneratePdfJob::dispatch(
builder: function ($pdf) use ($invoice) {
$pdf->setTitle("發票 #{$invoice->number}")
->addPage()
->setFont('Helvetica', '', 12)
->cell(0, 10, "發票 #{$invoice->number}");
},
outputPath: storage_path("app/invoices/{$invoice->id}.pdf"),
onSuccess: function (string $path) use ($invoice) {
$invoice->update(['pdf_path' => $path, 'status' => 'ready']);
Mail::to($invoice->customer)->send(new InvoiceReady($invoice));
},
onFailure: function (\Throwable $e) use ($invoice) {
$invoice->update(['status' => 'generation_failed']);
Log::error('PDF 產生失敗', [
'invoice' => $invoice->id,
'error' => $e->getMessage(),
]);
},
);佇列設定
指定佇列名稱、連線與延遲:
php
GeneratePdfJob::dispatch(
builder: $builder,
outputPath: $path,
)->onQueue('pdf-generation')
->onConnection('redis')
->delay(now()->addMinutes(5));重試與逾時
在 config/tcpdf-next.php 中設定預設值,或在派發時覆寫:
php
// config/tcpdf-next.php
'queue' => [
'connection' => env('TCPDF_QUEUE_CONNECTION', 'redis'),
'name' => env('TCPDF_QUEUE_NAME', 'pdf-generation'),
'tries' => 3,
'timeout' => 120,
'backoff' => [10, 30, 60],
],任務會使用指數退避策略:第一次重試等待 10 秒、第二次 30 秒、第三次 60 秒。
批次處理
使用 Laravel 的 Bus::batch() 同時產生多份 PDF:
php
use Illuminate\Support\Facades\Bus;
use Yeeefang\TcpdfNext\Laravel\Jobs\GeneratePdfJob;
$jobs = $invoices->map(fn (Invoice $invoice) => new GeneratePdfJob(
builder: function ($pdf) use ($invoice) {
$pdf->setTitle("發票 #{$invoice->number}")
->addPage()
->setFont('Helvetica', '', 12)
->cell(0, 10, "發票 #{$invoice->number}");
},
outputPath: storage_path("app/invoices/{$invoice->id}.pdf"),
));
Bus::batch($jobs)
->name('批次發票產生')
->onQueue('pdf-generation')
->allowFailures()
->then(function () {
Log::info('所有發票 PDF 已產生完畢');
})
->catch(function (\Throwable $e) {
Log::error('部分發票產生失敗', ['error' => $e->getMessage()]);
})
->finally(function () {
// 無論成敗皆執行
Notification::send($admins, new BatchCompleteNotification());
})
->dispatch();搭配 Blade 視圖
結合 Blade 模板產生更複雜的 PDF:
php
GeneratePdfJob::dispatch(
builder: function ($pdf) use ($order) {
$html = view('pdf.order-confirmation', [
'order' => $order,
'items' => $order->items,
])->render();
$pdf->setTitle("訂單確認 #{$order->id}")
->writeHtml($html);
},
outputPath: storage_path("app/orders/{$order->id}.pdf"),
);監控任務
使用 Laravel Horizon 或內建的 queue:monitor 指令追蹤 PDF 佇列狀態:
bash
php artisan queue:monitor pdf-generation --max=100下一步
- HTTP 回應 — 同步傳遞 PDF 至瀏覽器
- Pdf 門面 — 文件建立與測試輔助
- Laravel 設定 — 佇列相關設定選項