使用Laravel-dompdf优雅导出PDF

  • 2019-04-18
  • 0
  • 2

最近在工作中需要导出PDF操作,所以把一些使用技巧与踩过的一些坑记录一下。

laravel导出PDF的扩展还是挺多的,这里推荐两个都是出自同一个作者

barryvdh/laravel-dompdf 和 barryvdh/laravel-snappy

因为我也不知道哪一个相对较好,所以就选择了star多点的dompdf进行安装使用

1.安装

安装就不多说了,按照官方安装步骤就行了,安装配置文档点此

2.使用

$pdf = App::make('dompdf.wrapper');
$pdf->loadHTML('<h1>Test</h1>');

return $pdf->stream();

$pdf = PDF::loadView('pdf.invoice', $data);
return $pdf->download('invoice.pdf');

也可以链式操作

return PDF::loadFile(public_path().'/myfile.html')->save('/path-to/my_stored_file.pdf')->stream('download.pdf');

说明:

$pdf->stream();  //是直接页面输出
$pdf->download('invoice.pdf'); //文件下载

3.解决中文乱码 下载字体 msyh.ttf 字体文件放到 storage/fonts 文件夹下,目录不存在则先创建 在页面引用

@font-face {
  font-family: 'msyh';
  font-style: normal;
  font-weight: normal;
  src: url({{ storage_path('fonts/msyh.ttf') }}) format('truetype');
}
@page {size: 297mm 210mm; } //设置页面大小,也可以在配置中设置
body {
  font-size: 10px;
  font-family: msyh, DejaVu Sans,sans-serif;
}

4.页脚使用分页
后台代码

$pdf = PDF::loadView('pdf.content', [
'data' => $data,
]);

//开启PHP支持
$pdf->setOptions(['isPhpEnabled'=> true]);
$filename = date('YmdHis').'.pdf';

return $pdf->download($filename);

前端代码

<script type="text/php">
    if (isset($pdf)) {
        $text = "第 {PAGE_NUM} 页/共 {PAGE_COUNT} 页";
        $size = 8;
        $font = $fontMetrics->getFont("Verdana");
        $width = $fontMetrics->get_text_width($text, $font, $size) / 2;
        $x = ($pdf->get_width() - $width) / 2;
        $y = $pdf->get_height() - 35;
        $pdf->page_text($x, $y, $text, $font, $size);
    }
</script>

注:script脚本一定要放到body标签内

效果:

5.手动分页

想在内容的任意地方分页,需要使用css控制:

.page-break {
    page-break-after: always;
}

在需要分页的地方使用

<div class="page-break"></div>

6.报操作超时异常(数据量大的时候),只有在执行导出前加上以下代码:

set_time_limit(0);

7.遇到的报错

handleError(‘8’, ‘Undefined index: ‘, ‘url/vendor/dompdf/dompdf/lib/Cpdf.php’, ‘3547’, array(‘size’ => ’12’)) in #268

这是字体缓存问题,删除fonts文件夹里的dompdf_font_family_cache.php字体缓存文件,然后重新生成PDF即可。

最后技巧,遇到问题首先在项目的github里的issue里搜索解决方法,大部分问题都有解决方法,实在没有就去Google一下,最好不要用某度.

评论

  • gaowei回复

    你好,请问,$pdf = PDF::loadView(‘pdf.invoice’, $data); 这个$data 怎么使用啊,我值没办法给前端页面输出,卡在这里,能帮忙解答一下不

    • shanyuliang回复

      使用方法和 laravel 中的 return view(‘pdf.invoice’, $data) 中的 $data 使用方式一样