以前、給与計算のアプリを作成したときに、従業員全員の給与と経費をPDF化する機能が必要だったので、ここにメモしておきますー
目次
インストール
今回はlaravel-dompdfライブラリ
を使います!
https://github.com/barryvdh/laravel-dompdf
composerを使ってパッケージをインストール
composer require barryvdh/laravel-dompdf
config/app.php
のproviders
とaliases
を編集する
'providers' => [
...
Barryvdh\DomPDF\ServiceProvider::class,
];
'aliases' => [
...
'PDF' => Barryvdh\DomPDF\Facade::class,
];
次にPDF用の設定ファイルを用意しましょう
php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"
Copied File [/vendor/barryvdh/laravel-dompdf/config/dompdf.php] To [/config/dompdf.php]
Publishing complete.
そうするとconfig/dompdf.php
が作成されるので初期値の設定を変更していきましょう
詳しい設定については以下から確認してみてください
https://github.com/dompdf/dompdf/wiki/UnicodeHowTo#load-a-font-supporting-your-characters-into-dompdf
最初にフォントの設定を確認します
'font_dir' => storage_path('fonts/'), // advised by dompdf (https://github.com/dompdf/dompdf/pull/782)
これが初期値なので、フォントをインストールしていない場合はfonts
ディレクトリを作成して、そこに日本語フォントをインストールしましょう
日本語のIPAフォントのダウンロード先はこちらのTTFファイルをダウンロードしてください
https://ipafont.ipa.go.jp/old/ipafont/download.html
2020/09/29時点の四書体パックは下にあります
https://ipafont.ipa.go.jp/IPAfont/IPAfont00303.zip
mkdir storage/fonts
cd storage/fonts
wget https://ipafont.ipa.go.jp/IPAfont/IPAfont00303.zip
unzip IPAfont00303.zip
作成したファイルサイズの肥大化を防ぐために、下の設定も合わせてやりましょう!
またenable_font_subsetting
をtrue
にするとPDFデータに含むフォントファイルを使用しているものに制限できるのでファイルサイズを小さくすることができますー
コントローラ
//use PDF;を追記すれば\は必要ない
$pdf = \PDF::loadView('example', compact('example'));
//PDFダウンロードページを新規タブで開く
//return $pdf->stream('PDF名');
//ページ遷移なしでそのままダウンロード
return pdf->download('PDF名');
ダウンロード履歴をDBに保存したい場合はsave()
をこの前に記述すればいいですね
このコードの場合はリンクをクリックしたら自動でダウンロードされるので、ページに遷移したけどダウンロードしなかったという履歴が存在しないですね!
それとあまり使うことはないと思いますが、以下のコードを使うこともできます
PDF::loadHTML('<h1>Text Text Text</h1>');
ビュー
CSSの@font-faceを利用する方法
テンプレートのレイアウトを読み込んでしまうと、ずれてしまったので、
テンプレートは読み込まない方がいいと思います!
重要なのはここだけです笑
太文字のために二回@font-faceを指定してください
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style>
@font-face{
font-family: ipag;
font-style: normal;
font-weight: normal;
src:url('{{ storage_path('fonts/ipag.ttf')}}');
}
@font-face {
font-family: ipag;
font-style: bold;
font-weight: bold;
src: url("{{ storage_path('fonts/IPAfont00303/ipag.ttf') }}") format('truetype');
}
body {
font-family: ipag;
}
</style>
下は実際にテーブル表示をしてみましたー
テーブルは横に切れちゃっていたので全然できないながらもcssで調整しました
参考にはしないでください
長い文章をテーブル内で折り返すには<td>
タグにword-break
やword-wrap
を設定するといいみたいですー
<!DOCTYPE html>
<html lang='ja'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<style type='text/css'>
@font-face {
font-family: ipag;
font-style: normal;
font-weight: normal;
src: url("{{ storage_path('fonts/IPAfont00303/ipag.ttf') }}") format('truetype');
}
@font-face {
font-family: ipag;
font-style: bold;
font-weight: bold;
src: url("{{ storage_path('fonts/IPAfont00303/ipag.ttf') }}") format('truetype');
}
body {
font-family: ipag !important;
}
table th, table td {
padding: 10px 0;
text-align: center;
}
table tr:nth-child(odd) {
background-color: #eee;
}
thead {
display: table-header-group;
}
tfoot {
display: table-row-group;
}
table {
width: 100%;
border-collapse: collapse;
}
th {
word-break: break-all;
word-wrap: break-word;
}
tr {
page-break-inside: avoid;
}
</style>
</head>
<body>
<div align='right'>
出力日時{{ $now }}
</div>
<div align='center'>
{{ $year }}年{{ $month }}月
<table border=1 align='center'>
<thead>
<tr>
<th>名前</th>
<th>勤務日数</th>
<th>通常時間</th>
<th>深夜時間</th>
<th>総労働時間<br>深夜時間は25%増</th>
<th>時給</th>
<th>交通費</th>
<th>バイト代</th>
<th>支給総額</th>
</tr>
</thead>
<tbody>
@foreach ($employees as $employee)
<tr>
<th>{{ $employee->name }}</th>
@if (in_array($employee->id, $activeEmployeesId))
<th>{{ $employees[$employee->id - 1]->count }}</th>
<th>{{ $employees[$employee->id - 1]->normalTime }}</th>
<th>{{ $employees[$employee->id - 1]->nightTime }}</th>
<th>{{ $employees[$employee->id - 1]->totalTime }}</th>
<th>{{ config('common.hourlyFee.100') }}</th>
<th>{{ $employee->expense }}</th>
<th>{{ $employees[$employee->id - 1]->earnings }}</th>
<th>{{ $employees[$employee->id - 1]->totalPayment }}</th>
</tr>
@else
<th>0</th>
<th>0</th>
<th>0</th>
<th>0</th>
<th>
{{ config('common.hourlyFee.100') }}
</th>
<th>0</th>
<th>0</th>
<th>0</th>
</tr>
@endif
@endforeach
</tbody>
<tfoot>
<tr>
<th colspan=4>合計</th>
<th>{{ $sumTime }}</th>
<th></th>
<th>{{ $sumExpense }}</th>
<th>{{ $sumEarnings }}</th>
<th>{{ $sumPayment }}</th>
</tr>
</tfoot>
</table>
</body>
</html>
load_font.phpを使う方法
同様にフォントをダウンロードします
load_font.phpファイルはdomPDFには付属していないので
以下のURLからダウンロードしてください
https://github.com/dompdf/utils
ダウンロードしたファイルを/vendor/dompdf/dompdfの下に保存します
load_font.php
はvendor/phenx
ディレクトリに保存されている
php-font-lib
とphp-svg-lib
ディレクトリが必要みたいなので
vendor/dompdf/dompdf/lib
にコピーします
下のコマンドを参考にしてください
cd vendor/dompdf/dompdf
git clone https://github.com/dompdf/utils.git
cd lib
cp ../../../phenx/php-font-lib ./ #デフォルトで存在しないフォントを使用する場合に利用するライブラリ
cp ../../../phenx/php-svg-lib ./ #svgをレンダリングするために使用するライブラリ
vendor/dompdf/dompdf/lib
ディレクトリにhtml5lib
, php-font-lib
, php-svg-lib
があることを確認したら
load_font_.php
を実行します
cd ../../../../
php load_font.php ipag storage/fonts/ipag.ttf
うまくいけば、vendor/dompdf/dompdf/lib/fonts/ipag.ufm
ができていると思います
最後にfonts
ディレクトリにコピーしておしまい!
cp vendor/dompdf/dompdf/lib/fonts/* storage/fonts/
コントローラーの書き方は先に説明したのと同じで、
ビューの書き方がもう少し簡潔になります
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<style>
body {
font-family: ipag;
}
</style>
これでおっけいです
何かとPDF出力するときあると思うので是非試してみてください!