您好,登录后才能下订单哦!
# Laravel-snappy怎么导出PDF
## 前言
在现代Web开发中,生成PDF文档是一个常见需求。Laravel作为流行的PHP框架,通过`laravel-snappy`包提供了强大的PDF生成能力。本文将全面介绍如何使用`laravel-snappy`在Laravel项目中导出PDF文档,涵盖从安装配置到高级用法的完整流程。
## 一、laravel-snappy简介
### 1.1 什么是laravel-snappy
`laravel-snappy`是Laravel框架的一个包装包,它基于`wkhtmltopdf`命令行工具,能够将HTML内容转换为PDF或图像文件。与直接使用`wkhtmltopdf`相比,`laravel-snappy`提供了更友好的Laravel集成方式。
### 1.2 主要特性
- 支持PDF和图像生成
- 简单的API接口
- 支持Laravel视图系统
- 可配置的选项丰富
- 支持自定义页眉页脚
- 高性能转换
### 1.3 适用场景
- 生成发票/收据
- 创建报告文档
- 导出用户数据
- 生成合同/协议
- 任何需要打印友好的文档场景
## 二、环境准备与安装
### 2.1 系统要求
- PHP >= 7.3
- Laravel >= 6.0
- wkhtmltopdf二进制文件
### 2.2 安装wkhtmltopdf
#### Linux系统
```bash
# Ubuntu/Debian
sudo apt-get install wkhtmltopdf
# CentOS/RHEL
sudo yum install wkhtmltopdf
brew install --cask wkhtmltopdf
从wkhtmltopdf官网下载安装包并安装
通过Composer安装包:
composer require barryvdh/laravel-snappy
php artisan vendor:publish --provider="Barryvdh\Snappy\ServiceProvider"
这将在config目录下创建snappy.php配置文件。
打开config/snappy.php,主要配置项包括:
return [
    'pdf' => [
        'enabled' => true,
        'binary' => env('WKHTML_PDF_BINARY', '/usr/local/bin/wkhtmltopdf'),
        'timeout' => false,
        'options' => [],
        'env' => [],
    ],
    'image' => [
        'enabled' => true,
        'binary' => env('WKHTML_IMG_BINARY', '/usr/local/bin/wkhtmltoimage'),
        'timeout' => false,
        'options' => [],
        'env' => [],
    ],
];
在.env文件中添加:
WKHTML_PDF_BINARY=/usr/bin/wkhtmltopdf
WKHTML_IMG_BINARY=/usr/bin/wkhtmltoimage
路径应根据实际安装位置调整。
Laravel 5.5+会自动注册服务提供者,旧版本需在config/app.php中手动添加:
'providers' => [
    // ...
    Barryvdh\Snappy\ServiceProvider::class,
],
'aliases' => [
    // ...
    'PDF' => Barryvdh\Snappy\Facades\SnappyPdf::class,
    'SnappyImage' => Barryvdh\Snappy\Facades\SnappyImage::class,
],
use PDF;
public function generatePdf()
{
    $html = '<h1>测试PDF</h1><p>这是一个测试PDF文档。</p>';
    $pdf = PDF::loadHTML($html);
    return $pdf->download('test.pdf');
}
创建视图文件resources/views/pdf/report.blade.php:
<!DOCTYPE html>
<html>
<head>
    <title>报告文档</title>
</head>
<body>
    <h1>{{ $title }}</h1>
    <p>生成时间: {{ date('Y-m-d H:i:s') }}</p>
    <table>
        <tr>
            <th>ID</th>
            <th>名称</th>
        </tr>
        @foreach($items as $item)
        <tr>
            <td>{{ $item['id'] }}</td>
            <td>{{ $item['name'] }}</td>
        </tr>
        @endforeach
    </table>
</body>
</html>
控制器中使用:
public function generateReport()
{
    $data = [
        'title' => '销售报告',
        'items' => [
            ['id' => 1, 'name' => '产品A'],
            ['id' => 2, 'name' => '产品B'],
        ]
    ];
    
    $pdf = PDF::loadView('pdf.report', $data);
    return $pdf->download('report.pdf');
}
下载到浏览器:
return $pdf->download('filename.pdf');
内联显示:
return $pdf->inline('filename.pdf');
保存到服务器:
$pdf->save(public_path('storage/reports/report.pdf'));
获取原始内容:
$content = $pdf->output();
$pdf = PDF::loadView('pdf.report', $data)
    ->setOption('page-size', 'A4')
    ->setOption('margin-top', '20mm')
    ->setOption('margin-bottom', '20mm')
    ->setOption('margin-left', '10mm')
    ->setOption('margin-right', '10mm');
创建页眉视图resources/views/pdf/header.blade.php:
<div style="text-align: center; border-bottom: 1px solid #ccc;">
    <h2>公司名称</h2>
</div>
使用页眉页脚:
$pdf = PDF::loadView('pdf.report', $data)
    ->setOption('header-html', view('pdf.header')->render())
    ->setOption('footer-html', view('pdf.footer')->render());
确保CSS文件可被访问:
$pdf = PDF::loadView('pdf.report', $data)
    ->setOption('user-style-sheet', public_path('css/pdf.css'));
| 选项 | 描述 | 示例值 | 
|---|---|---|
| page-size | 页面尺寸 | A4, Letter | 
| orientation | 方向 | portrait, landscape | 
| dpi | 分辨率 | 300 | 
| encoding | 编码 | UTF-8 | 
| no-outline | 禁用大纲 | true | 
| margin-top | 上边距 | 20mm | 
| header-html | 页眉HTML | http://example.com/header | 
| footer-html | 页脚HTML | http://example.com/footer | 
| user-style-sheet | 自定义CSS | /path/to/style.css | 
$pdf = Cache::remember('report-pdf', 3600, function() use ($data) {
    return PDF::loadView('pdf.report', $data)->output();
});
return response($pdf)
    ->header('Content-Type', 'application/pdf')
    ->header('Content-Disposition', 'attachment; filename="report.pdf"');
创建任务:
php artisan make:job GeneratePdfJob
在handle方法中:
public function handle()
{
    $pdf = PDF::loadView('pdf.report', $this->data)
        ->save(storage_path('app/public/reports/'.$this->filename));
}
控制器中调用:
GeneratePdfJob::dispatch($data, 'report.pdf');
使用静态编译的wkhtmltopdf二进制文件,性能更好:
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.bionic_amd64.deb
sudo dpkg -i wkhtmltox_0.12.6-1.bionic_amd64.deb
解决方案:
确保HTML指定UTF-8编码:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
使用支持中文的字体:
body {
   font-family: 'Noto Sans CJK SC', 'Microsoft YaHei', sans-serif;
}
安装中文字体:
sudo apt-get install fonts-noto-cjk
确保图片使用绝对路径:
<!-- 错误 -->
<img src="images/logo.png">
<!-- 正确 -->
<img src="{{ public_path('images/logo.png') }}">
优化建议:
$pdf->setTimeout(300);
查看日志:
tail -f storage/logs/laravel.log
调试模式:
$pdf->setOption('debug', true);
public function generateInvoice(Order $order)
{
    $pdf = PDF::loadView('pdf.invoice', [
        'order' => $order,
        'company' => Company::first()
    ])
    ->setOption('header-html', view('pdf.invoice-header')->render())
    ->setOption('footer-html', view('pdf.invoice-footer')->render());
    
    return $pdf->download("invoice-{$order->number}.pdf");
}
public function batchGenerate()
{
    $reports = Report::where('status', 'pending')->get();
    
    foreach ($reports as $report) {
        $filename = "report-{$report->id}.pdf";
        $path = storage_path("app/reports/{$filename}");
        
        PDF::loadView('pdf.custom-report', ['report' => $report])
            ->save($path);
            
        $report->update([
            'status' => 'completed',
            'pdf_path' => $path
        ]);
    }
}
Mail::to($user->email)->send(new ReportMail($report));
// 在Mailable类中
public function build()
{
    return $this->view('emails.report')
        ->attachData(
            PDF::loadView('pdf.report', ['data' => $this->report])->output(),
            'report.pdf',
            ['mime' => 'application/pdf']
        );
}
优点: - 纯PHP实现,无需外部依赖 - 安装简单
缺点: - CSS支持有限 - 性能较差 - 复杂布局渲染问题多
优点: - 功能丰富 - 支持条形码等特性
缺点: - API复杂 - 学习曲线陡峭 - HTML渲染能力弱
laravel-snappy提供了强大而灵活的PDF生成能力,通过与Laravel框架的深度集成,开发者可以轻松实现各种PDF导出需求。本文从安装配置到高级用法,全面介绍了如何使用这个工具包。正确使用时,记得:
希望本文能帮助你在Laravel项目中高效实现PDF导出功能。
| 命令 | 描述 | 
|---|---|
composer require barryvdh/laravel-snappy | 
安装包 | 
php artisan vendor:publish --provider="Barryvdh\Snappy\ServiceProvider" | 
发布配置 | 
sudo apt-get install wkhtmltopdf | 
安装wkhtmltopdf(Ubuntu) | 
| Laravel版本 | laravel-snappy版本 | 
|---|---|
| 10.x | ^1.0 | 
| 9.x | ^1.0 | 
| 8.x | ^0.4.0 | 
| 7.x | ^0.4.0 | 
| 6.x | ^0.4.0 | 
”`
这篇文章全面介绍了Laravel-snappy导出PDF的各个方面,从基础安装到高级用法,包含了约4700字的内容。文章采用Markdown格式,包含代码块、表格、列表等元素,便于阅读和理解。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。