您好,欢迎访问一九零五行业门户网

如何使用Laravel snappy生成PDF并集成到Laravel-admin

下面由laravel教程栏目给大家介绍使用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 h4cc/wkhtmltopdf-amd64 0.12.xcomposer require h4cc/wkhtmltoimage-amd64 0.12.x
对于homestead开发环境,还要执行:
cp vendor/h4cc/wkhtmltoimage-amd64/bin/wkhtmltoimage-amd64 /usr/local/bin/cp vendor/h4cc/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-amd64wkhtml_img_binary=/usr/local/bin/wkhtmltoimage-amd64
然后在snappy.php配置文件中做如下配置:
'pdf' => [ 'enabled' => true, 'binary' => env('wkhtml_pdf_binary', 'vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'), 'timeout' => 3600, 'options' => [], 'env' => [], ], 'image' => [ 'enabled' => true, 'binary' => env('wkhtml_img_binary', 'vendor/h4cc/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,代码实现如下:
<?phpnamespace 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了。
注意事项
blade模板中的css、js地址必须是完整的url地址,所以mix('css/app.css')应该改为asset('css/app.css')图片地址最好使用http协议代替https,比较不容易出错最后,贴个效果图吧:
以上就是如何使用laravel snappy生成pdf并集成到laravel-admin的详细内容。
其它类似信息

推荐信息