[0027]Lalavel5.7 日本語でPDF作成し表示もしくは自動ダウンロード

■インストール

この例のLalavelフレームワークのバージョンは5.7です。

領収書などデータベースから取得したデータを利用し、動的にPDFを作成し、表示もしくはダウンロードしたいのでlaravel-dompdfを利用します。

まず、ssh接続し、Lalavelのプロジェクト配下でcomposerを利用し、laravel-dompdfをインストールします。

Lalavel5.7の場合、バージョンを指定しないと最新とバージョンが合わないので、0.8.5を指定しました。

Lalavel5.1の場合、0.7.0を指定しました。

              
#Lalavelのプロジェクト配下に移動
% cd /home/failibere/www/sample
#laravel-dompdfをインストール
#-vvvのオプションをつけて進捗を確認します。バージョン指定しないとエラーになったのでバージョン指定
#Lalavel5.7の場合
% composer require barryvdh/laravel-dompdf:~0.8.5 -vvv
#Lalavel5.1の場合
% composer require barryvdh/laravel-dompdf:~0.7.0 -vvv
              
            

次にconfig/app.phpのサービスプロバイダーとファサードに追加します。

app.php

              
 'providers' => [
        :
  Barryvdh\DomPDF\ServiceProvider::class,
  ],
  'aliases' => [
        :
  'PDF' => Barryvdh\DomPDF\Facade::class,
  ],
              
            

■ファイルサイズ軽量化

ファイルサイズが重いので軽量化のため、config配下にdompdfの設定ファイルdompdf.phpを作成します。

ssh接続し、Lalavelのプロジェクト配下でartisanコマンドを実行します。

              
#Lalavelのプロジェクト配下に移動
% cd /home/failibere/www/sample
#artisanコマンド実行
% php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"
Copied File [/vendor/barryvdh/laravel-dompdf/config/dompdf.php] To [/config/dompdf.php]
              
            

config配下にdompdf.phpが作成されたので、dompdf.phpを開いて、enable_font_subsettingをfalseからtrueに設定変更します。

dompdf.php

              
"enable_font_subsetting" => true,
              
            

■日本語文字化け修正

日本語は文字化けするので日本語フォントのIPAフォントのダウンロードを行います。

外部サイトhttps://moji.or.jp/ipafont/ipa00303/のTTFファイル「4書体パック」のzipをローカルにダウンロードし解凍します。

Lalavelのプロジェクト配下のstorage配下にfontsフォルダを作成し、権限をゆるくしておきます。

              
#Lalavelのプロジェクト配下に移動
% cd /home/failibere/www/sample/storage
#フォルダ作成
% mkdir fonts
% chmod 777 fonts
              
            

今作成したstorage/fonts配下に先ほど解凍したttfファイルを配置します。

■PDF作成

準備ができたので、コントローラ(Controller)を作成します。

この例ではコントローラ(Controller)の関数名はtestです。

PDFで画像表示したい場合、普段のURL参照はできなかったため、Controller側で指定しView側へ渡します。

$image_path = '/home/failibere/www/sample/public/img/sign01.png';$image_data = base64_encode(file_get_contents($image_path));

この例ではビュー(View)はresources/views/pdf配下にindex.blade.phpを作成したので、loadViewに渡すのは「'pdf.index'」になっています。

PDF表示の場合はreturn $pdf->stream();です。

PDFダウンロードの場合はreturn $pdf->download('[PDF名]');です。

XXXController.php

              
public function test(){
	$setArr = array();
	$setArr['name'] = "小川 太郎";
	$setArr['price'] = "45000";
	$image_path = '/home/failibere/www/sample/public/img/sign01.png';
	$image_data = base64_encode(file_get_contents($image_path));
	$pdf = PDF::loadView('pdf.index', compact(['image_data','setArr']))
	->setPaper('a4')->setWarnings(false);
	//return $pdf->download('receipt.pdf');
	return $pdf->stream();
}
              
            

次に、Viewを作成します。

文字化け回避のため、metaでcharset=utf-8を指定し、styleに「@font-face」「body」を指定します。

H1タグなどのfont-weightはこれにより文字化けしなくなりましたが太さは変わりませんでした。

スタイルは効くものと効かないものがある気がします。。がシンプルなものを出したいので気にしないでおきます(汗)

画像表示はController側から渡ってきた$image_dataを利用します。

<img src="data:image/png;base64,{{ @$image_data }}">

index.blade.php

              
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>領収書</title>
<style>
@font-face {
    font-family: ipag;
    font-style: normal;
    font-weight: normal;
    src: url('{{ storage_path('fonts/ipag.ttf') }}') format('truetype');
}
@font-face {
    font-family: ipag;
    font-style: bold;
    font-weight: bold;
    src: url('{{ storage_path('fonts/ipag.ttf') }}') format('truetype');
}
body {
    font-family: ipag !important;
}
</style>
</head>
<body>
<div class="container">
		<div class="clearfix">
          <table align="right" width="30%">
            <tbody><tr>
              <td width="30%">No.</td>
              <td width="20%" align="center">:</td>
              <td width="50%" align="right">ET0059006002</td>
            </tr>
            <tr>
              <td width="30%">発行日</td>
              <td width="20%" align="center">:</td>
              <td width="50%" align="right">2022-05-01</td>
            </tr>
            <tr>
              <td width="30%">領収日</td>
              <td width="20%" align="center">:</td>
              <td width="50%" align="right">2022-05-01</td>
            </tr>
          </tbody></table>
        </div>
        <div>
            <h1 style="color: #32afaf;">領収書</h1>
          <p style="font-size: 17px">
            下記、正に領収致しました。
          </p>
        </div><br>
    <div>
      <table style="font-size: 22px">
        <tbody><tr>
          <td width="1%" valign="middle" style="padding-right:40px;">
            <p style="border-bottom: dashed 2px #32afaf;">宛名</p>
          </td>
          <td width="300px" valign="middle" style="padding:20px;">
            <span class="lead">{{@$setArr['name']}}</span>
          </td>
          <td width="1%" valign="middle">
            様
          </td>
        </tr>
        <tr>
          <td width="1%" valign="middle" style="padding-right:40px;">
            <p style="border-bottom: dashed 2px #32afaf;">金額</p>
          </td>
          <td width="300px" valign="middle" align="right" style="padding:20px;">
            <span class="lead">{{@$setArr['price']}}円</span>
          </td>
          <td width="1%" valign="middle">
            (税込)
          </td>
        </tr>
        <tr>
          <td width="1%" valign="middle" style="padding-right:40px;">
            <p style="border-bottom: dashed 2px #32afaf;">但書</p>
          </td>
          <td width="300px" valign="middle" style="padding:20px;" colspan="2">
            <span class="lead">ご旅行代金として(クレジットカードにて入金)</span>
          </td>
        </tr>
        <tr>
          <td width="1%" valign="middle" style="padding-right:40px;">
            <p style="border-bottom: dashed 2px #32afaf;">期間</p>
          </td>
          <td width="300px" valign="middle" style="padding:20px;" colspan="2">
            <span class="lead">2022年05月10日〜2022年05月11日</span>
          </td>
        </tr>
      </tbody></table>
    </div><br>
    <div class="clearfix">
      <table align="right" width="30%" style="font-size: 20px">
        <tbody><tr>
          <td colspan="2" width="100%" align="right">SYSTEM Failibere</td>
        </tr>
        <tr>
          <td width="50%">システム フェイリベル</td>
          <td width="50%" align="right"><img src="data:image/png;base64,{{ @$image_data }}"></td>
        </tr>
        <tr>
          <td colspan="2" width="100%" align="right">TEL:03-XXXX-XXXX</td>
        </tr>
        <tr>
          <td colspan="2" width="100%" align="right">FAX:03-XXXX-XXXX</td>
        </tr>
       </tbody>
      </table>
    </div>
  </div>
</body>
</html>
              
            

無事表示されました!

■追記★太字に対応

やはり太字に対応したい!ということで、日本語対応のときと同じく、太字対応のttfをダウンロードし、Lalavelのプロジェクト配下のstorage配下のfontsフォルダに配置します。

migmix-2p-20150712.zipをダウンロードし、中に入っている「migmix-2p-regular.ttf」と「migmix-2p-bold.ttf」の2つを配置します。

配置したらViewのhead内のstyleの@font-faceとbodyのfont-familyを修正します。

index.blade.php

              
<style>
@font-face {
    font-family: migmix;
    font-style: normal;
    font-weight: normal;
    src: url('{{ storage_path('fonts/migmix-2p-regular.ttf') }}') format('truetype');
}
@font-face {
    font-family: migmix;
    font-style: bold;
    font-weight: bold;
    src: url('{{ storage_path('fonts/migmix-2p-bold.ttf') }}') format('truetype');
}
body {
    font-family: migmix;
}
</style>
			
            

style="font-weight:bold"が効くようになりました!