laravel5.1で日本語ファイル名のPDF出力する実装方法
参考URL http://cly7796.net/wp/php/to-create-a-pdf-with-laravel/
1, 前提
テンプレートとなるPDFファイルを用意して、PHPで文字や数字を出力する(Webフォームから申込用紙PDF出力など)
2, 使うライブラリ(パッケージ)
tcpdfとfpdi-tcpdf
laravelらしくcomposerにインストールしてもらうので、composer.jsonに記述を追加(tecnickcom/tcpdf と setasign/fpdi-tcpdf)
“require”: {
“php”: “>=5.5.9”,
“laravel/framework”: “5.1.*”,
“tecnickcom/tcpdf”: “6.2.*”,
“setasign/fpdi-tcpdf”: “1.6.1”
},
composer updateでインストールしてもらう。
3, 適当な用紙PDFを、storage/pdf/test.pdfにアップロードしておく。
4, PdfController.phpなど適当なコントローラーを生成してテストする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
use FPDI; // PDF用パッケージ class PdfController extends Controller { // PDFインスタンスを生成 $receipt = new FPDI(); // PDFの余白(上左右)を設定 $receipt->SetMargins(0, 0, 0); // 自動改ページをOFF(白紙の2ページ目を作らない) // 第二引数は、ページ下端からのマージン(デフォは2cm) $receipt->SetAutoPageBreak(false, 0 ); // ヘッダー・フッターの出力を無効化 $receipt->setPrintHeader(false); $receipt->setPrintFooter(false); // 1ページ目を生成 $receipt->AddPage(); // テンプレートを読み込み $receipt->setSourceFile(storage_path() . '/pdf/test.pdf'); // 読み込んだPDFの1ページ目のインデックスを取得 $tplIdx = $receipt->importPage(1); // 読み込んだPDFの1ページ目をテンプレートとして使用 $receipt->useTemplate($tplIdx, null, null, null, null, true); // 書き込む文字列のフォントを指定(kozminproregularは、tcpdfがサポートしている日本語フォント) // 特に日本語フォントにこだわりが無ければ、これで充分!! $receipt->SetFont("kozminproregular", "", 10); //XY座標は小数点以下まで、こまかく指定出来る! // 発行日 $receipt->SetXY(150, 34.3); $receipt->Write(0, date("Y年m月d日")); // 商品リストなど繰り返し表示する時は、がんばって微調整する! $receipt->SetFontSize(9); $i = 0; $ajastet = 4.35; foreach ($carts as $cart){ // 商品コード $receipt->SetXY(16, 92.3+($ajastet*$i)); $receipt->Write(0, $cart->id); // 商品名 $receipt->SetXY(42, 92.3+($ajastet*$i)); $receipt->Write(0, $cart->name); // 単価 $receipt->SetXY(153, 92.3+($ajastet*$i)); $receipt->Cell(5, 5, number_format($cart->price), 0, 0, 'R'); // 数量 $receipt->SetXY(164, 92.3+($ajastet*$i)); $receipt->Cell(5, 5, $cart->qty, 0, 0, 'R'); // 金額 $receipt->SetXY(188, 92.3+($ajastet*$i)); $receipt->Cell(5, 5, number_format($cart->subtotal), 0, 0, 'R'); $i++; } // ココから合計値(金額など右寄せしたい場合は、WriteではなくCellを使う) // 小計 $receipt->SetXY(188, 179); $receipt->Cell(5, 5, Cart::subtotal(), 0, 0, 'R'); // 消費税 $receipt->SetXY(188, 184); $receipt->Cell(5, 5, Cart::tax(), 0, 0, 'R'); // 合計金額 $receipt->SetXY(188, 194); $receipt->Cell(5, 5, Cart::total(), 0, 0, 'R'); // 英数字ファイル名なら、そのまま出力できる。 // $receipt->Output('test.pdf', 'I'); // ブラウザに直接表示 // $receipt->Output('test.pdf', 'D'); // PDFファイルをダウンロード // tcpdfはデフォルトでは日本語ファイル名に対応していないので、自分でヘッダ出力する必要がある!! // https://teratail.com/questions/42269 $name = '日本語.pdf'; // ファイル名をマルチバイトに設定すると、TCPDFがファイル名を強制的に置き換えてしまう。 // @see http://www.tailtension.com/cakephp/510/ $string = $receipt->Output($name, 'S'); // browscap を利用する // @see http://php.net/manual/ja/function.get-browser.php // browscap.ini が存在しないときは、取得する if (empty(ini_get('browscap'))) { if (!file_exists('browscap.ini')) { $url = 'https://browscap.org/stream?q=Lite_PHP_BrowsCapINI'; $contents = file_get_contents($url); file_put_contents('browscap.ini', $contents); } ini_set('browscap', 'browscap.ini'); } $browser = get_browser(); // クライアントがWindowsの時はファイル名を SJIS-WIN に変換する if (preg_match("/win/i", $browser->platform)) { $name = mb_convert_encoding($name, 'SJIS-WIN', 'UTF-8'); } // IEでUTF-8の日本語ファイル名だと文字化けするが、chromeやFireFoxではsjis-winでも文字化けしないので、そもそも判定不要? // $name = mb_convert_encoding($name, 'SJIS-WIN', 'UTF-8'); header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Transfer-Encoding: binary "); header('Content-Type: application/octet-streams'); header("Content-Disposition: attachment; filename=\"{$name}\""); } |
5, browscapというブラウザを判定するためのPHP関数を追加するために、自動ダウンロード&インストールがCentOSだと上手く行かなかった(xamppでは問題無しだったのでパーミッション?)
参考URL https://adan.jp.net/blog/program/1363
しょうがないので、手動でダウンロード&インストールしたら問題なく動作した。
これでテンプレートPDF+PHPで書き込んだ内容のファイルがダウンロード出来るようになるはず!