您好,登錄后才能下訂單哦!
小編給大家分享一下怎么使用Laravel snappy生成PDF并集成到Laravel-admin,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
Laravel snappy
之前使用過python+wkhtmltopdf來導出PDF,wkhtmltopdf確實是很強大的工具,有很多的頁面定制選項,而且會自動幫你把網上的圖片抓取下來,渲染到PDF上。這次想在Laravel-admin中實現導出PDF的功能,于是找到了Laravel snappy這個擴展包,它是對https://github.com/KnpLabs/snappy這個項目的封裝,好巧的是,它也是通過調用wkhtmltopdf程序來生成PDF的。
安裝與配置
// 安裝擴展包 composer require barryvdh/laravel-snappy // 將wkhtmltopdf作為composer依賴 // 對于64位系統,使用: composer require h5cc/wkhtmltopdf-amd64 0.12.x composer require h5cc/wkhtmltoimage-amd64 0.12.x
對于homestead開發環境,還要執行:
cp vendor/h5cc/wkhtmltoimage-amd64/bin/wkhtmltoimage-amd64 /usr/local/bin/ cp vendor/h5cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64 /usr/local/bin/ chmod +x /usr/local/bin/wkhtmltoimage-amd64 chmod +x /usr/local/bin/wkhtmltopdf-amd64
安裝完后,在app.config
中alias
鍵設置facade別名(可選):
'PDF' => Barryvdh\Snappy\Facades\SnappyPdf::class, 'SnappyImage' => Barryvdh\Snappy\Facades\SnappyImage::class,
最后發布資源文件:
php artisan vendor:publish --provider="Barryvdh\Snappy\ServiceProvider"
在.env
文件中添加:
WKHTML_PDF_BINARY=/usr/local/bin/wkhtmltopdf-amd64 WKHTML_IMG_BINARY=/usr/local/bin/wkhtmltoimage-amd64
然后在snappy.php
配置文件中做如下配置:
'pdf' => [ 'enabled' => true, 'binary' => env('WKHTML_PDF_BINARY', 'vendor/h5cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'), 'timeout' => 3600, 'options' => [], 'env' => [], ], 'image' => [ 'enabled' => true, 'binary' => env('WKHTML_IMG_BINARY', 'vendor/h5cc/wkhtmltoimage-amd64/bin/wkhtmltoimage-amd64'), 'timeout' => 3600, 'options' => [], 'env' => [], ],
使用
通過加載渲染blade模板生成PDF:
$pdf = PDF::loadView('pdf.invoice', $data); //pdf.invoice是你的blade模板 return $pdf->download('invoice.pdf');
通過外部鏈接生成:
return PDF::loadFile('http://www.github.com')->inline('github.pdf');
通過html生成,并做各種設置,并保存之:
PDF::loadHTML($html)->setPaper('a4')->setOrientation('landscape')->setOption('margin-bottom', 0)->save('myfile.pdf') // 更多選項可查看wkhtmltopdf的手冊:https://wkhtmltopdf.org/usage/wkhtmltopdf.txt
Laravel-admin導出功能改造
Laravel-admin默認的導出格式是csv,這里將把它改造成想要的PDF格式。
Laravel-admin導出原理簡單分析
查看導出按鈕,可得到這三個導出入口格式大概如下:
http://hostname/posts?_export_=all // 導出全部 http://hostname/posts?_export_=page%3A1 // 導出當前頁 http://hostname/posts?_export_=selected%3A1 // 導出選定的行
其有對應的控制器方法應該是index
,從這里追查開去,可以找到/vendor/encore/laravel-admin/src/Grid.php
中有:
public function render(){ $this->handleExportRequest(true); try { $this->build(); } catch (\Exception $e) { return Handler::renderException($e); } $this->callRenderingCallback(); return view($this->view, $this->variables())->render();}
如果url中有帶_export=…參數,將會執行$this->handleExportRequest(true);
這里面的代碼:
protected function handleExportRequest($forceExport = false){ if (!$scope = request(Exporter::$queryName)) { return; } // clear output buffer. if (ob_get_length()) { ob_end_clean(); } $this->disablePagination(); if ($forceExport) { $this->getExporter($scope)->export(); // 這里將調用某個類的export方法 }}
最關鍵的是export
方法,我們將新建一個繼承AbstractExporter
類的類,實現我們自己想要的導出邏輯。另外,看getExporter
方法:
protected function getExporter($scope){ return (new Exporter($this))->resolve($this->exporter)->withScope($scope);}
我們還可以在子類中改寫withScope
進行一些參數設置、攔截。
開始改造導出功能
了解了基本的原理,再參考下Laravel-admin的文檔,我們就可以著手改下導出功能了。
首先,創建一個擴展,如app/Admin/Extensions/PdfExporter.php
,代碼實現如下:
<?php namespace App\Admin\Extensions; use Encore\Admin\Grid\Exporters\AbstractExporter; use Encore\Admin\Grid\Exporter; use PDF; class PdfExporter extends AbstractExporter { protected $lackOfUserId = false; public function withScope($scope){ // 你自己的一些處理邏輯,比如: /*if ($scope == Exporter::SCOPE_ALL) { if(request()->has('user_id')) { $this->grid->model()->where('user_id', request()->user_id); } else { $this->lackOfUserId = true; } return $this; }*/ return parent::withScope($scope); } public function export() { // 具體的導出邏輯,比如: if($this->lackOfUserId) { $headers = [ 'Content-Encoding' => 'UTF-8', 'Content-Type' => 'text/html;charset=UTF-8', ]; response('請先篩選出用戶', 200, $headers)->send(); exit(); } $author = $this->grid->model()->getOriginalModel()->first()->user->user_name; $this->grid->model()->orderBy('add_time', 'desc'); // 按年-月分組數據 $data = collect($this->getData())->groupBy(function ($post) { return Carbon::parse(date('Y-m-d',$post['add_time']))->format('Y-m'); })->toArray(); // 渲染數據到blade模板 $output = PDF::loadView('pdf.weibo', compact('data'))->setOption('footer-center', '[page]')->output(); $headers = [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => "attachment; filename=$author.pdf", ]; // 導出文件, response(rtrim($output, "\n"), 200, $headers)->send(); exit; } }
接著,在app/Admin/bootstrap.php
中注冊擴展:
Exporter::extend('pdf-exporter', PdfExporter::class);
最后,對應的在Grid
方法中使用:
protected function grid(){ // 其他邏輯... // 添加導出PDF的擴展 $grid->exporter('pdf-exporter'); return $grid;}
這樣,點擊導出按鈕的時候,就可以下載PDF了。
注意事項
mix('css/app.css')
應該改為asset('css/app.css')
最后,貼個效果圖吧:
以上是“怎么使用Laravel snappy生成PDF并集成到Laravel-admin”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。