Laravel8でPDFを出力する(laravel-dompdf)

laravel環境でPDF出力する案件がありましたので、対応方法をご紹介
上記はLaravel-adminの画面ですが、もちろん普通にLaravelで利用できます。
確認済みのLaravelのバージョンは8.Xです。
6.X以降であれば問題なく動作するはずです。
LaravelでPDF出力する方法
パッケージが一番手っ取り早い。有名どころでは下記の2つ
- laravel-dompdf
- Snappy
はじめはSnappyで取り組んでいたのですが、一部うまくいかない部分があったのでlaravel-dompdfへ方針転換
それらを比較するとこんな感じ
| larave-dompdf | snappy | |
| インストールの手間 | ○ | × |
| 機能 | △ | ○ |
| 日本語対応 | × | × |
snappyの方が高機能、らしい。いまのところlarava-dompdfでも不満か感じません。
どちらも海外プラグインのため日本語化するのはパッケージインストール以外に作業が必要です。これが面倒。でも大事な作業なのでがんばりましょう。
Laravel-dompdfのインストール
コマンドこの通り
$ composer require barryvdh/laravel-dompdf Using version ^0.8.5 for barryvdh/laravel-dompdf
インストールが完了したら、サービスプロバイダとエイリアスに登録する必要があります。
両方とも「config/app.php 」ファイルに追記していきます。
まずはサービスプロバイダ部分
'providers' => [
・
・
・
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
Barryvdh\DomPDF\ServiceProvider::class,
次にエイリアス部分
'aliases' => [
・
・
・
Illuminate\View\ViewServiceProvider::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
'PDF' => Barryvdh\DomPDF\Facade::class,
これでインストールと準備が完了しました。
PDFの呼び出し
呼び出し方はbladeテンプレートを呼び出す方法とほとんど同じです。
route設定
まずはroute.phpにパスとコントローラの設定を記述します。今回は顧客氏名などをPDFに出力する必要があったので、パラメータとしてcustomer_idを渡しています。
下記のサンプルはlarave-admin側にコントローラを設定する方法になります。パスにご注意ください。
$router->get('/pdf/dl/{customer_id}', 'PdfController@index')->name('pdf.dl');
$router->get('/pdf/view/{customer_id}', 'PdfController@view')->name('pdf.view');
コントローラ設定
namespace App\Admin\Controllers;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use Barryvdh\DomPDF\Facade as PDF;
use Carbon\Carbon;
use Encore\Admin\Layout\Content;
class PdfController extends Controller
{
public function index($customer_id)
{
$customer = Customer::whereId($customer_id)->first();
$date = new Carbon();
$pdf=PDF::loadView('admin.nouhin',compact('customer','date'));
return $pdf->download('納品書.pdf'); //こちらがダウンロード用機能
}
public function view($customer_id)
{
$customer = Customer::whereId($customer_id)->first();
$date = new Carbon();
return view('admin.nouhin',compact('customer','date')); //こちらがブラウザ表示用機能
}
}
indexがPDFをダウンロードする機能、viewがブラウザ上にそのままPDFを開く機能としています。
Using $this when not in object context エラー
注意事項というより私がはまったこと。
IDE補完機能で「PDF」の宣言に対するインポートをuse宣言していたのですが、気付かぬうちに下記になっていました。
use Barryvdh\DomPDF\PDF;
正しくは上のサンプルにもある通り、Facadeを利用する必要があります。
use Barryvdh\DomPDF\Facade as PDF;
これに気付かず数時間無駄にしました、、
『Error Using $this when not in object context』というエラーに遭遇したらインポート宣言を見直してみてください。
use Barryvdh\DomPDF\PDF
ではなく
use Barryvdh\DomPDF\Facade as PDF;
です!!
laravel-dompdf日本語化
ここまででPDFの出力は完了したかと思います。しかし、出力されたPDFを見ると
?????
のように文字化けしているはずです。海外製プラグインなのでそのままでは日本語が表示できません。
下記の手順で日本語対応が必要です。
load_font.phpダウンロード
IPAフォントをダウンロードします。
明朝とゴシック2つの書体があります。2書体パックをダウンロードしておいた方が後で手間がないかと思います。
ダウンロードしたらLaravelをインストールしたディレクトリ直下にtempなどの適当なディレクトリを作成し保存します。

フォントファイルインストール
$ php load_font.php ipaexg temp/ipaexg.ttf
ゴシックフォントをインストールする場合は「ipaexg」の2か所を「ipaexm」に書き換えてください。
フォントのコピー
load_font.phpを実行してvendor/dompdf/dompdf/lib/fontsディレクトリに作成された、ipagexf.ttf, ipagexg.ufm, dompdf_font_family_cache.phpをstorage/fontsにコピーします。
Bladeテンプレートでフォントを指定
設定が完了したらPDF出力用のテンプレートを修正していきます。このBladeテンプレートでインストールしたフォントをCSSで指定します。
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>PDF</title>
<style>
body {
font-family: ipaexg;
}
</style>
</head>
<body>
<h1>PDFテスト&lt;/h1>
</div>
</body>
</html>
これで日本語のPDFが出力されるようになりました。
Undefined offset: 12239 エラーが出力される場合
フォントファイルの相性なのか、エラーが出る場合があります。フォントファイルを変更してみましょう。
私はMigMixというフォントを利用させて頂き解消しました。
laravel-dompdf小ネタ
PDFでQRコードを表示する場合の記述
<img src="data:image/png;base64, {{ base64_encode(QrCode::format('png')->size(100)->generate('Make me into an QrCode!')) }} ">
laravel-dompdfまとめ
LaravelからPDF出力する場合にはlarave-dompdfを利用することで対応できるました。日本語化が少し手間ですが、一度慣れてしまえば大丈夫そうです。
HTMLのテンプレートをベースに手軽にPDF出力できるので、ぜひ利用してみてください。


