You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Laravel应用中生成并导出PDF文件?求实现示例

Laravel生成并导出PDF的推荐方案与实现示例

方案选择建议

  • barryvdh/laravel-dompdf:适合大多数常规场景,无需额外系统依赖,与Blade视图无缝集成,学习成本低,能满足发票、收据这类布局不复杂的PDF生成需求。
  • barryvdh/laravel-snappy:依赖wkhtmltopdf(需单独安装系统级依赖),支持复杂CSS3、JavaScript渲染和精确的分页/页眉页脚控制,适合对PDF格式精度要求极高的场景。

基于dompdf的实现示例(预约关联支付的发票场景)

1. 安装扩展包

composer require barryvdh/laravel-dompdf

(可选)发布配置文件,用于自定义PDF的纸张大小、编码等设置:

php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"

2. 构建控制器逻辑

创建InvoiceController.php,实现PDF生成、下载、服务器存储的核心逻辑:

<?php

namespace App\Http\Controllers;

use App\Models\Appointment;
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Storage;

class InvoiceController extends Controller
{
    public function generateInvoice($appointmentId)
    {
        // 获取预约及关联的支付数据(需确保Appointment模型已定义payment关联)
        $appointment = Appointment::with('payment')->findOrFail($appointmentId);

        // 加载Blade视图并生成PDF
        $pdf = Pdf::loadView('invoices.receipt', compact('appointment'));

        // 选项1:直接在浏览器下载PDF
        return $pdf->download("invoice-{$appointment->id}.pdf");

        // 选项2:将PDF存储到服务器(示例存储在storage/app/public/invoices目录)
        // $storagePath = "invoices/invoice-{$appointment->id}.pdf";
        // Storage::put($storagePath, $pdf->output());
        // return response()->download(storage_path("app/public/{$storagePath}"));
    }
}

3. 创建Blade发票模板

在resources/views/invoices/receipt.blade.php编写发票HTML结构,直接调用关联数据:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>发票 #{{ $appointment->id }}</title>
    <style>
        body { font-family: Arial, sans-serif; padding: 20px; }
        .invoice-header { text-align: center; border-bottom: 1px solid #ddd; padding-bottom: 15px; }
        .invoice-info { margin: 20px 0; display: flex; justify-content: space-between; }
        .table { width: 100%; border-collapse: collapse; margin-top: 30px; }
        .table th, .table td { border: 1px solid #ddd; padding: 10px; text-align: left; }
        .table th { background-color: #f5f5f5; }
        .footer { margin-top: 40px; text-align: right; color: #666; }
    </style>
</head>
<body>
    <div class="invoice-header">
        <h1>服务收据</h1>
        <p>预约编号:{{ $appointment->id }}</p>
    </div>

    <div class="invoice-info">
        <div>
            <p><strong>客户姓名:</strong> {{ $appointment->client_name }}</p>
            <p><strong>预约日期:</strong> {{ $appointment->appointment_date->format('Y-m-d H:i') }}</p>
        </div>
        <div>
            <p><strong>支付状态:</strong> {{ $appointment->payment->status == 'paid' ? '已支付' : '未支付' }}</p>
            <p><strong>支付时间:</strong> {{ $appointment->payment->paid_at?->format('Y-m-d H:i') }}</p>
        </div>
    </div>

    <table class="table">
        <thead>
            <tr>
                <th>服务项目</th>
                <th>金额(元)</th>
                <th>支付描述</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>{{ $appointment->service_name }}</td>
                <td>{{ number_format($appointment->payment->amount, 2) }}</td>
                <td>{{ $appointment->payment->payment_description }}</td>
            </tr>
        </tbody>
    </table>

    <div class="footer">
        <p>感谢您的惠顾!</p>
    </div>
</body>
</html>

4. 配置路由

在routes/web.php添加生成发票的路由:

use App\Http\Controllers\InvoiceController;

Route::get('/invoice/{appointmentId}', [InvoiceController::class, 'generateInvoice'])->name('invoice.generate');

基于Snappy的快速说明

如果需要复杂的PDF渲染(如精确分页、页眉页脚、JS交互),可选择Snappy:

  1. 安装扩展包:composer require barryvdh/laravel-snappy
  2. 安装wkhtmltopdf系统依赖(根据操作系统下载对应版本并配置路径)
  3. 控制器逻辑与dompdf基本一致,仅需替换Facade:
use Barryvdh\Snappy\Facades\SnappyPdf;

// 生成PDF
$pdf = SnappyPdf::loadView('invoices.receipt', compact('appointment'));
// 下载或存储逻辑与dompdf完全相同

内容的提问来源于stack exchange,提问作者nflux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 01:32:35