【Laravel】PDFを動的に作成・出力する方法:laravel-dompdf
2024.04.04 /
本記事ではLaravelにおける、laravel-dompdfを使用してPDFを動的に作成・出力する方法について詳しく解説していきます。
データベース内のデータを基にPDFを生成し、ユーザーにダウンロードさせる機能はWebアプリケーションでよく利用されます。
Laravelではlaravel-dompdfというパッケージを使うことでHTMLやCSSでカスタマイズしたPDFを簡単に出力することができます。
ぜひ本記事を通して、laravel-dompdfを使ってPDFを動的に作成・出力する方法について理解を深めてください。
ここではLaravel10を使用しています。
Laravel:PDFを動的に作成・出力するとは
Laravelで作成したWebアプリケーションでは、データベース内のデータやユーザーから提供されたデータを基に、独自にカスタマイズしたPDFを生成・出力する機能を簡単に導入できます。
例えばデータベースのデータから領収書や請求書、レポート、契約書などのPDFを簡単に生成・ダウンロードできるようにできます。
このように動的にPDFを出力するにはLaravelではDOMPDFやmPDF、Snappyといったライブラリを利用します。
PDFの内容はBladeファイルに記述したHTMLとCSSでカスタマイズします。
本記事ではライブラリにDOMPDFを利用した方法を解説していきます。
laravel-dompdf(DOMPDF)によるPDFの出力方法
Laravelでlaravel-dompdfを利用してPDFを出力する流れは以下の通りです。
- DOMPDFライブラリのインストール
- プロバイダを登録(Laravel 5.5以上では不要)
- コントローラーの生成
- ルーティング(web.php)の設定
- コントローラーの設定
- PDFのビュー設定
- ダウンロードボタンの追加
ここではデータベースに登録されたスタッフの情報をPDFでダウンロードすることを想定してルートやコントローラーを記述していきます。実際にご自身のWebアプリケーションで実装する場合は、適宜コードを修正してください。
DOMPDFライブラリのインストール
Composerを使用してPDFの出力に必要なDOMPDFをインストールします。
Composerとは
ComposerとはPHPのライブラリ依存性管理ツールです。Composerはライブラリやパッケージの依存関係の管理などを行い、システムが問題なく動く環境を構築する役割をしています。
例えばライブラリAを利用する場合、先にライブラリBをインストールする必要があるといったことが頻繁にあります。これをライブラリの依存といいます。
この依存関係をComposerは管理しており、依存関係にあるライブラリをまとめてインストールしてくれます。
そのためComposerを使ってLaravelをインストールすることで、問題なく動く環境が構築されるということです。
コマンドプロンプトを起動して以下コマンドを実行します。
composer require barryvdh/laravel-dompdf
DOMPDFのインストールが完了したらcomposer.jsonを開いて、laravel-dompdfが追加されたことを確認してください。
"require": {
"php": "^8.1",
"barryvdh/laravel-dompdf": "^2.1",
プロバイダを登録(Laravel 5.5以上では不要)
DOMPDFのプロバイダを「config/app.php」に登録します。以下の通りコードを追記してください。また使用しているLaravelがバージョン5.5以上の場合は本作業は不要です。
'providers' => [
// ...
Barryvdh\DomPDF\ServiceProvider::class,
],
'aliases' => [
// ...
'PDF' => Barryvdh\DomPDF\Facade::class,
],
コントローラーの生成
PDFの生成およびダウンロードを実行するコントローラーを生成します。
以下コマンドを実行してコントローラーを作成します。またここではシングルアクションコントローラーを使います。
php artisan make:controller Staff/DownloadPdfController --invokable
シングルアクションコントローラとは
シングルアクションコントローラ(Single Action Controller)とは単一のアクション(メソッド)しかルーティングされない制約をもったコントローラーです。
通常のコントローラーでは複数のアクション(indexやshow、create、storeなど)を用意しますが、シングルアクションコントローラは一つのコントローラーに単一のアクションしか用意しません。
- コントローラーの肥大化を防ぐ
- 各ルートがどのコントローラアクションにマッピングされているかが明確になる
- 単一のアクションしか持たないためコードが簡潔で読みやすい
- メンテナンス性が向上
- 使用しなくなったら削除しやすい(単一のアクションしか持たないため)
シングルアクションコントローラについて詳しくは以下記事をご参照ください。
【Laravel】シングルアクションコントローラとは:コマンドやルーティングについて
ルーティング(web.php)の設定
PDFを生成して出力(ダウンロード)するためのルートを設定します。「routes/web.php」に以下のようなルートを設定してください。
Route::get('staff/download/{staffl}', \App\Http\Controllers\Staffl\DownloadPdfController::class)->name('staff.download');
コントローラーの設定
「コントローラーの生成」で作成されたコントローラに以下のようにコードを記述します。
use App\Models\Staff;
use PDF;
class DownloadPdfController extends Controller
{
/**
* Handle the incoming request.
*/
public function __invoke(Staff $staff)
{
$pdf = PDF::loadView('export.pdf', compact('staff'));
return $pdf->download('staff-details.pdf');
}
}
上記コードではPDFをビュー(Blade)にデータを渡して生成し、それをユーザーにダウンロードさせます。
PDFのビュー設定
PDFに表示する内容はビュー(blade)に記述したHTMLが出力されます。そこでまずはresources/viewの配下にexportフォルダを作成し、その中にpdf.blade.phpというファイルを作成します。
bladeファイルを作成したら以下のようにコードを記述してPDFの内容を作成します。
<html>
<head>
<title>スタッフ詳細</title>
{{-- ここにスタイルやフォントなどの設定を記述 --}}
</head>
<body>
<h1>{{ $staff->name }}</h1>
{{-- staffの詳細情報を表示 --}}
</body>
</html>
ダウンロードボタンの追加
ユーザーがPDFをダウンロードするためのボタンなどを追加します。例えば以下のようなボタンのコードを追加してください。
<a href="{{ route('staff.pdf', $staff->id) }}"><button type="button" class="btn btn-outline-info"><i class="bi bi-file-earmark-arrow-down-fill"></i> スタッフ詳細</button></a>
ユーザーがこのボタンをクリックするとコントローラー側で生成されたPDFがダウンロードされます。
日本語対応:日本語フォントの導入
ここまでの操作でPDFを出力できるようになりましたが、日本語の表示は「???」と表示されてしまいます。これはDOMPDFがデフォルトで「DejaVu Sans」フォントを使用するからです。
PDFに日本語を表示したい場合は日本語のフォントファイルが必要となります。ここでは文字情報技術促進協議会のサイトからIPAexフォントをダウンロードして利用する方法をご紹介します。
まずは以下の流れでIPAexフォントをダウンロードしてください。
- IPAexフォントのダウンロードサイトへアクセスする
- 最新版のIPAexフォントのリンクをクリックする
- 希望する書体のリンクをクリックする
上記の操作でフォントファイルがダウンロードされます。ZIPファイルなので解凍しておきます。
storageフォルダにfontsフォルダを作成し、その中に解凍したフォルダ内にある拡張子ttfのフォントファイルを格納します。
次にPDF出力用のbladeファイルに日本語フォントを適応させます。以下のようにコードを記述してください。
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>スタッフ詳細:{{ $staff->name }}</title>
<style>
@font-face {
font-family: ipaexg;
font-style: normal;
font-weight: normal;
src: url('{{ storage_path('fonts/ipaexg.ttf') }}');
}
html, body, textarea {
font-family: ipaexg, sans-serif;
}
</style>
{{-- ここにスタイルやフォントなどを設定 --}}
上記のコードを追加することで、出力されるPDFが日本語対応になります。