Laravel-dompdf が使いやすくなってた件

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

いろいろとやることが多くてついブログをサボってしまいました(汗)

現在の開発で PDFが必要になったので、Laravel開発ではデファクトスタンダードの「laravel-dompdf」を使うことにしました。

何度もこのパッケージは使っているんですけど、実は日本語を使うとなると composer のルールを破ったりキャッシュを自分で作ったりと少し使いにくいものでした。

※実際にはlaravel-dompdfではなく、元となってるdompdfが原因です。

なので、今回もまた同じ作業が必要かと思っていたら、さすが日進月歩のウェブの世界。

新しいlaravel-dompdfではめんどうな作業をショートカットできるようになってました。

そこで!その感動を原動力にlaravel-dompdfで日本語を使う方法をまとめてみたいと思います。

開発環境: Laravel 7.x、laravel-dompdf 0.8.6

※この記事は、Laravel 5.5向けに作成された内容に加筆修正されたものです。

まずはインストール

まずはパッケージをインストールしましょう。

composer require barryvdh/laravel-dompdf

Laravel 5.5以上なら面倒なconfig/app.phpへの作業も必要ありません。ホント便利になりました!

フォントを準備

laravel-dompdfを使って日本語出力をするには、以前と同じく日本語フォントが必要になります。

なので、以下から IPAフォントをダウンロードしてstorage/fontsに設置しましょう。(フォルダがなければ自分で作って権限を777に変更しておいてください)

storage/app/fontsではないので注意!

【フォントのダウンロードURL】
https://moji.or.jp/ipafont/ipafontdownload/

ビューとコントローラー

フォントの設置が終わったら、次はビューコントローラーを作成します。
まずはPDFでアウトプットされるビューを作成しましょう。

※テスト的に書いているので、ファイル名などはお好みで変更してください。

/resources/views/generate_pdf.blade.php

<!doctype html>
<html>
<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/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>
日本語の表示
</body>
</html>

注意すべき点は、@font-faceの部分です。
ここに指定したフォントが PDFで利用できるようになります。

なお、@font-faceが2つあるのは通常の文字と、太字に対応するためです。
(最初ずっと表示できないなと思っていたら太文字を指定していなかった罠にハマっていました😅)

そして、bodyにもfont-familyで指定して念の為!importantで強調しています。また、metaにもutf-8をセットしておくといいでしょう。

これでビューはOKです!

コントローラー

次にコントローラーを作りましょう。
これはほぼ定型文ですね。

/app/Http/Controllers/HomeController.php

class HomeController extends Controller
{
    public function generate_pdf() {

        $pdf = \PDF::loadView('generate_pdf');
        return $pdf->stream('title.pdf');

    }

    // 省略

内容としては、先ほどのビューを loadView()で読み込んで、後は stream()を呼ぶだけです。

(なお、このときに laravel-dompdf が必要なファイルを自動で作成してくれます。なんて有能なパッケージなんでしょう!)

そして、PDFをダウンロードしたい場合は、return部分を、

return $pdf->download('title.pdf');

にするだけでOK!
楽ちんですね😊✨

テーブル内で長い文章を自動で折り返す方法

【追記:2019.11.26】dompdf 0.8.3

長い文章をテーブル内で折り返すには、以下のようにtdタグにword-break, word-wrapを設定してください。

/resources/views/generate_pdf.blade.php

<!doctype html>
<html>
<head>
    <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') }}') format('truetype');
        }
        body {
            font-family: ipag !important;
        }
        table {
            border-collapse: collapse;
            width: 100%;
        }
        td {
            border:1px solid #000;
            word-break:break-all;
            word-wrap:break-word;
        }

    </style>
</head>
<body>
<div>
    <table>
        <tr>
            <td style="width:50%;">
                <div style="padding:15px;">
                    テストテストテストテストテストテストテストテストテストテストテストテストテストテストテストテストテスト
                </div>
            </td>
            <td>test</td>
            <td>test</td>
        </tr>
        <tr>
            <td>test</td>
            <td>test</td>
            <td>test</td>
        </tr>
        <tr>
            <td>test</td>
            <td>test</td>
            <td>test</td>
        </tr>
    </table>
</div>
</body>
</html>

これを実行したものが以下になります。

設定を変更する

【追記:2020.3.12】

dompdfでは様々な設定が変更できるようになっています。

もし変更したい場合、以下のコマンドで設定ファイルをコピーしてください。

php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"

すると、「config/dompdf.php」というファイルが作成されるので、この中で設定を変更できます。

では、ひとつずつ見ていきましょう!

show_warnings

エラー(Exception)を有効にするかどうか。

orientation

縦長か横長の選択。

  • 縦長: portrait
  • 横長: landscape

font_dir

フォントを設置するフォルダ。

font_cache

フォントのキャッシュを設置するフォルダ。

temp_dir

一時的なデータを保存するフォルダ。

chroot

ルートのフォルダ。
このフォルダ内に限定して操作が実行されます。

※脆弱性が含まれる可能性があります。PDFの脆弱性についてをご覧ください。

enable_font_subsetting

trueにすると、フォントを埋め込まないPDFが作成されます。(つまり、ファイルサイズが小さくなりますが、閲覧者の環境にフォントがインストールされている必要があります)

pdf_backend

レンダリングに利用するライブラリ。
使えるパラメータは次のとおりです。

  • PDFLib
  • CPDF
  • GD
  • auto

DOMPDF_PDFLIB_LICENSE

ライセンス表記(商用PDFlibを使っている場合のみ)

default_media_type

HTMLのメディアタイプ。
使えるパラメータは次のとおりです。

  • screen
  • tty
  • tv
  • projection
  • handheld
  • print
  • braille
  • aural
  • all

default_paper_size

PDFのサイズ。

default_font

どのフォントを使うか。

dpi

解像度。

enable_php

PDFでphpを有効にするかどうか。

※脆弱性が含まれる可能性があります。PDFの脆弱性についてをご覧ください。

enable_javascript

PDFでJavaScriptを有効にするかどうか。

※脆弱性が含まれる可能性があります。PDFの脆弱性についてをご覧ください。

enable_remote

例えば、<img src="http://example.com/****">などインターネットの参照を有効にするかどうか。

※脆弱性が含まれる可能性があります。PDFの脆弱性についてをご覧ください。

font_height_ratio

行間の比率。

enable_html5_parser

HTML5 Lib parserを有効にするかどうか。

𠮷(つちよし)の文字化けを修正する方法

こちらにつきましては、noteで公開していますので、以下からご覧ください。

📝 詳細ページ: 【Laravel/dompdf】 𠮷(つちよし)の文字化けを修正する方法

PDFの脆弱性について

【追記:2020.3.12】

例えば、enable_phpでPHPを有効にし、enable_remoteでインターネットへの参照を有効にしてしまうと、PDFの中に「自由にPHPが実行できる」脆弱性が含まれることになります。

また、chroot/にした場合、全フォルダへの権限が有効になり危険です。そのため、これらの設定を有効にする場合は注意が必要です。

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

と、いうことで今回は作業が楽になったlaravel-dompdfを紹介しました。
みなさんの開発のお役にたてたら光栄です。

ではでは〜!

このエントリーをはてなブックマークに追加       follow us in feedly