PHPでテンプレートPDFに動的に文字や数値を追記し出力する方法(TCPDF&FPDI)
請求書や領収書のテンプレートがあり、そちらに対して動的に文字・数値を追記し出力させるというシステムを実装したかった。以前にHTML / CSSで作成したページをPDF化するという記事を書いたが、こちらでは見た目がシンプルすぎて業務で使うには微妙。何か方法は無いかと探したところTCPDF&FPDIの組み合わせが良さそうだったので以下に実装方法をメモ。
目次
TCPDF
以下からダウンロードし展開したものを適当なディレクトリにアップロードする。
https://github.com/tecnickcom/tcpdf
尚、非公式とのことだが以下リファレンスが日本語で見やすい。
また、必須では無いが今回はフォントを「arialunicid0」に指定したいため過去記事を参考の上で該当ファイルをアップロードしておく。
FPDI
以下からダウンロードし展開したものを適当なディレクトリにアップロードする。
https://www.setasign.com/products/fpdi/downloads/
テンプレートの用意
今回はテストのため以下のようなテンプレートサイトからエクセルファイルをダウンロードし、PDF化した上で適当なディレクトリにアップロードしておく。
https://template.the-board.jp/receipt_templates/article/receipt_template_001
ちなみに今回用意したテスト用PDFは以下の通り。
https://taitan916.info/sample/pdf/test/test.pdf
ソースコード
<?php //TCPDF&FPDIの読み込み include('./tcpdf/tcpdf.php'); include('./fpdi/autoload.php'); $flg = false; do{ if( !$_GET['name'] || !$_GET['price'] ){ break; } //TCPDFオブジェクト作成 $pdf = new setasign\Fpdi\Tcpdf\Fpdi(); //余白無し $pdf->SetMargins(0, 0, 0); //自動で改ページさせない $pdf->SetAutoPageBreak(false, 0); //ヘッダーフッター無し $pdf->setPrintHeader( false ); $pdf->setPrintFooter( false ); //テンプレートPDF読み込み $pdf->setSourceFile('./test.pdf'); //新ページを作成 $pdf->AddPage(); //読み込んだPDFの1ページ目を取得 $tpl = $pdf->importPage(1); $pdf->useTemplate($tpl, null, null, null, null, true); //通常フォントサイズ設定 $pdf->SetFont('arialunicid0', '', 17); //宛名 $pdf->Text(15, 34, htmlspecialchars( $_GET['name'] ) ); //金額 $pdf->Text(70, 57, htmlspecialchars( number_format($_GET['price']) ) ); $pdf->Output("output.pdf", "I"); }while(0); ?>
上記は領収書の宛名と金額をGETパラメータで受け取り、出力するという内容のソースコードになる。サンプルのためバリデートや例外処理は適当なため、本番実装時はその辺りを適宜変更する。念のため以下サンプルページとなる。
https://taitan916.info/sample/pdf/test/?name=%E3%81%82%E3%81%82%E3%81%82&price=10000
使用感など
自動改行は難しい
見積書などを発行する際に商品名が長く、改行したいというケースがあった。ただ文字数に応じて自動で改行するというのは難しい(方法はあるかもしれないが見つけられなかった)。
そのため商品名を出力する前に「何文字以上の場合は改行」という処理をPHP側で行わざるを得なかった。
テンプレートの注意点
見積書などで商品名を複数記載する可能性があるような場合、こちらのような1行ずつ仕切られているようなテンプレートよりも、こちらのように仕切られていないテンプレートの方が使いやすい。
というのも1行ずつ仕切られているテンプレートで、長い商品名を記述する場合に改行且つ文字サイズを小さくする必要が出てくる。そうすると見づらくなる上に処理が面倒臭くなる。
仕切られていなければ改行処理は必要なものの文字サイズの調整は不要なので楽。
複数ページに渡る場合
見積書などで商品数自体が多く、1ページでは足りないケースがあった。1枚のPDFで複数ページを発行というのもできそうではあるが、その場合は2ページ目以降のテンプレートファイルも必要になりそう。
そのため、商品数が多くなる場合は複数枚のPDFファイルを発行し、zip圧縮した上でダウンロードさせる形を取った。
文字の右寄せ、中央寄せは難しい
左寄せは簡単だけど右・中央寄せは難しい(方法はあるかもしれないが見つけられなかった)。ただ請求書番号とか数値に関してはゼロ詰めにして桁数をあらかじめ決めておけばできなくはない。
所感
色々と制限はあるもののテンプレートファイルさえ用意すればそれなりの見た目になるので業務で十分に使えそう。
関連記事
-
-
お名前.comの共用サーバー(SD)でのphp設定
画像のアップロードフォームを作っていて、そういえば最大ファイルサイズは? と思っ ...
-
-
PHPでCSVファイルを作って開くと「SYLKファイルが云々」のアラートが出た
データベースのログを整形してCSVファイルを生成し、ダウンロード及びエクセルで開 ...
-
-
imgタグで作成したグラフをjQueryでリアルタイムに動かす
このグラフをリアルタイムプレビューさせる。 ■サンプル http://sampl ...
-
-
CodeIgniterでCronを実行する方法
CodeIgniterで特定の処理をCronで自動で実行したかった。以下に設定方 ...
-
-
PHPでcharset
header("Content-Type: text/html; charset ...
-
-
PHPで一括出力ではなく、ひとつずつ順次に出力する方法
PHPで重たい処理とかをしている際に、途中報告みたいな形で順次出力させる方法のメ ...
-
-
FPDIで「This PDF document probably uses~~」エラーの対処方法
FPIDであるPDFを読み込ませようとすると「This PDF document ...
-
-
PHPで画像の削除
やりたい事↓↓ --------------- 画像の削除。削除ボタンを押すと「 ...
-
-
PHPでディレクトリの作成と削除
PHPでユーザID毎にディレクトリを作成しその中にキャッシュファイルを格納したか ...
-
-
エラー管理
<? /*エラー管理*/ //画面上にエラー表示させるかどうか。0⇒非表示 ...