業務で Laravel
のアプリケーションにおいて、「既存のPDFファイルを読み込み、文字入れをした上でPDFファイルを出力する」 という実装を行ったので、備忘録としてまとめておきます。
使用するライブラリ
- TCPDF
PHPでPDFを生成できるライブラリ。
https://github.com/tecnickcom/tcpdf
- FPDI
既存のPDFを読み取り、TCPDFのテンプレートとして使用できるようにするライブラリ。
Download the FPDI tool from ▷ setasign.com
上記の2つのライブラリを使用するので、先にインストールしておきます。
※インストール方法については以下の記事を参照。
【TCPDF+FPDI】PHPで領収書PDFに文字を出力する方法
実装の概要
全体の流れは以下の通りです。
【事前準備】
テンプレートとして使用するPDFを用意し、プロジェクトディレクトリに保存しておく。
【実装の流れ】
-
FPDI
インスタンスを生成し、テンプレートとなるPDFをセットする。 - テンプレートのPDF上に、座標を指定して文字を乗せていく。
- PDFファイルをブラウザに出力する。
では実際のコード例を挙げて説明していきます。
実装方法
1. PDFの初期設定
まずは FPDI
インスタンスを生成し、テンプレートとなるPDFを指定、各種初期設定を行います。
<?php
// 追記
use setasign\Fpdi\Tcpdf\Fpdi;
public function downloadPdf()
{
// FPDIインスタンス生成
$pdf = new Fpdi();
// フォントの設定
$pdf->SetFont('kozminproregular');
// テンプレートとなるPDFファイルを指定(ファイルまでのパスを引数に渡す)
$pdf->setSourceFile('template.pdf');
// 新規ページをセット
$pdf->addPage();
// テンプレートPDFの1ページ目を読み込み
$page = $pdf->importPage(1);
// 読み込んだページをテンプレートに使用
$pdf->useTemplate($page);
// 各種初期設定
$pdf->setFontSize(12);
$pdf->setMargins(0, 0, 0);
$pdf->setCellPadding(0);
$pdf->setAutoPageBreak(true, 0);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
}
2. テンプレートのPDFに文字入れを行う
PDFに文字入れをしていきます。
文字入れについては、以下3つの方法を紹介します。
用途に応じて使い分けるのが良いかと思います。
-
Text
メソッド
指定した座標に文字列を出力する。 -
Cell
メソッド
指定した座標にセルを表示し、セルの中に指定した文字列を出力することができる。
文字列は、センタリングもしくは左右どちらかに揃えて配置できる。(高さは中央に配置される)
文字列にリンクを貼ることもできる。 -
MultiCell
メソッド
Cell
メソッドの働きに加え、文字列がセルの右端に達すると改行してくれる。
※他にも使用できるメソッドは色々あります。
以下のサイトが分かりやすかったので是非見てみてください。
ツール紹介
上記のどのメソッドを使う場合でも、PDF上の座標を指定して文字列やセルを配置する必要があります。
座標を取得する方法は色々あるかと思いますが、私は Adobe Acrobat Reader DC
を使いました。
PDFリーダー | Adobe Acrobat Reader DC
PDFファイルを Adobe Acrobat Reader DC
で開き、
「表示→表示切り替え→定規とグリッド→定規」(もしくはCtrl+R)
とクリックしていくと、座標を示す定規が表示されます。
Text
メソッド
$pdf->Text(x軸の座標, y軸の座標, 出力する文字列);
Text
メソッドの引数は以下の3つです。
・第1引数…基点のx軸の座標(左からの位置)
・第2引数…基点のy軸の座標(上からの位置)
・第3引数…出力する文字列
指定した座標を基点(文字列の左上)として、文字列が出力されます。
Cell
メソッド
Cell
メソッドを使う場合は、先に SetXY
メソッドで基点とする座標を指定し、その位置に Cell
メソッドでセルを設置します。
Cell
メソッドでセルを設置することで、Cell
メソッドの第3引数に指定した文字列も出力されます。
$pdf->SetXY(x軸の座標, y軸の座標);
$pdf->Cell(幅, 高さ, 出力する文字列, (bool)セルの枠線の有無, セルを作った後のXY座標定義, 揃え, (bool)セルの塗りつぶし, リンク先URL);
Cell
メソッドは上記の通り、たくさん引数を指定することが出来ます。
使用していて感じたメリット・デメリットを下に挙げます。
【メリット】
・Text
メソッドと比べて、セルの高さの中央に文字列を配置してくれるので便利。
・リンクを張ることも出来る。
【デメリット】
・文字列の長さがセルの幅を超えた場合でも、自動的に改行は行われない。
MultiCell
メソッド
Cell
メソッドの進化版のようなものと認識しています。
文字列の長さがセルの幅を超えた場合、自動的に改行を行ってくれます。
$pdf->SetXY(x軸の座標, y軸の座標);
$pdf->Cell(幅, 高さ, 出力する文字列, (bool)セルの枠線の有無, 揃え, (bool)セルの塗りつぶし);
Cell
メソッドと同様に、先に SetXY
メソッドで基点とする座標を指定し、その位置に MultiCell
メソッドでセルを設置します。
【備考】
・セルの中に複数行の文字列を出力する場合はこっちが便利。
・ Cell
メソッドのデフォルトではセルの高さの中央に文字列を配置するが、MultiCell
メソッドのデフォルトではセルの左上を基点として文字列を配置する。
3. PDFファイルをブラウザに出力する
最後に Output
メソッドを使ってPDFファイルを出力します。
$pdf->Output(); // 画面出力
Output
メソッドの引数は以下の2つです。
・第1引数…ファイル名(指定しなければ doc.pdf
という名前になる)
・第2引数…出力モード(I
:ブラウザへ出力, D
:ファイルダウンロード, F
:ローカルファイルとして保存, S
:文字列としてドキュメントを返す)
以上の手順で、既存のPDFに文字入れをしてPDFを出力することが出来ました。
参考記事