Edited at

PHPでPDF帳票を出力する方法(TCPDF + FPDI)

More than 3 years have passed since last update.

PHPでPDFを出力する場合、PDFlibFPDFharu などさまざまなソリューションがありますが、たとえば、請求書や納品書といった、レイアウトが複雑なデザインの帳票を出力したいときには、 既存のPDFをテンプレートとして活用し、そこに必要な文字だけ配置していく ことでソースコードをシンプルに保つことができます。

既存のPDFをテンプレートとして読み込むことができ、かつ無償で活用できるライブラリとして、TCPDFFPDI の組み合わせをご紹介します。


テンプレートとなるPDFを作成する

PDFの読み込みを行うFPDIは、有償のパーサーを別途導入しない場合、PDF 1.5以上のファイルをパースすることができません。テンプレートとなるPDFファイルは PDF 1.4以下の圧縮形式で作成する必要があります。

また、PHP上から文字を配置する場合、座標を使用するため(左から10mm、上から20mmの位置から…といった具合)、Illustratorなどのソフトを使用したほうが効率的です。

たとえば、上の例ではIllustratorを使用して領収書のひな形を作成し、ドキュメント上に X : 42mm / Y : 108mm の位置に 幅 : 56mm × 高さ : 10mm のグレーのボックスを配置しています。ここにPHPを使って宛名を差し込んでいきます。

IllustratorからPDF 1.4互換のファイルを作成する

Illustrator CCの場合、「ファイルの種類」で「Adobe PDF」を選択し、続いて表示されるダイアログ上の、「互換性のある形式」で「Acrobat 5(PDF 1.4)」を選択します。


ライブラリをダウンロードする


TCPDF



  1. TCPDFをダウンロードします。ドキュメントなどが必要でなければ tcpdf_min_* を選択すればよいでしょう。

  2. ダウンロードしたファイルは解凍して、PHPのinclude_path上に tcpdf というフォルダ名で配置しました。Symfony2で使用する場合は、libフォルダなどを作成し、autoload.phpに以下のように追記します。


autoload.php

$loader = require __DIR__.'/../vendor/autoload.php';

AnnotationRegistry::registerLoader(array($loader, 'loadClass'));

// include_pathを追加する
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../lib');

return $loader;



フォント


  1. 日本語のフォントを使用したいので、今回は MigMixフォント を使用させてもらいます。MigMix 2Pをダウンロードしたら、解凍して migmix-2p-bold.ttfmigmix-2p-regular.ttftcpdf/fonts/ フォルダに配置します。


  2. tcpdf/fonts/ フォルダにはPHP実行ユーザに書き込み権限が必要ですので、パーミッションを変更しておきましょう。


FPDI



  1. FPDIをダウンロードします

  2. ダウンロードしたファイルは解凍して、TCPDFを配置した tcpdf フォルダ内に配置しましょう。この時点で tcpdf フォルダ内は以下のような配置になっているはずです。

lib/

tcpdf/
fonts/
migmix-2p-bold.ttf
migmix-2p-regular.ttf
fpdi.php
…(ほか、FPDIのファイル群)
tcpdf.php
…(ほか、TCPDFのファイル群)


ライブラリを使用して、PDFを出力する

準備はここまでです。

あとは、PHPからテンプレートとなるPDFを読み込み、文字列を追加して出力します。

以下はSymfony2のコントローラですが、もちろんほかのフレームワークでも同様の書き方でPDFを出力可能かと思います。


PdfController.php

<?php

namespace Awesome\DemoBundle\Controller;

// include_pathからTCPDFとFPDIを読み込む
require_once('tcpdf/tcpdf.php');
require_once('tcpdf/fpdi.php');

use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class DeliveriesPdfController extends Controller
{
public function listAction(Request $request)
{
$receipt = new \FPDI();

// PDFの余白(上左右)を設定
$receipt->SetMargins(0, 0, 0);

// ヘッダーの出力を無効化
$receipt->setPrintHeader(false);

// フッターの出力を無効化
$receipt->setPrintFooter(false);

// フォントを登録
$fontPathRegular = $this->getLibPath() . '/tcpdf/fonts/migmix-2p-regular.ttf';
$regularFont = $receipt->addTTFfont($fontPathRegular, '', '', 32);

$fontPathBold = $this->getLibPath() . '/tcpdf/fonts/migmix-2p-bold.ttf';
$boldFont = $receipt->addTTFfont($fontPathBold, '', '', 32);

// ページを追加
$receipt->AddPage();

// テンプレートを読み込み
$receipt->setSourceFile($this->getLibPath() . '/tcpdf/tpl/receipt.pdf');

// 読み込んだPDFの1ページ目のインデックスを取得
$tplIdx = $receipt->importPage(1);

// 読み込んだPDFの1ページ目をテンプレートとして使用
$receipt->useTemplate($tplIdx, null, null, null, null, true);

// 書き込む文字列のフォントを指定
$receipt->SetFont($regularFont, '', 11);

// 書き込む文字列の文字色を指定
$receipt->SetTextColor(255, 0, 0);

// X : 42mm / Y : 108mm の位置に
$receipt->SetXY(42, 108);

// 文字列を書き込む
$receipt->Write(0, '山田 太郎');

$response = new Response(
// Output関数の第一引数にはファイル名、第二引数には出力タイプを指定する
// 今回は文字列で返してほしいので、ファイル名はnull、出力タイプは S = String を選択する
$receipt->Output(null, 'S'),
200,
array('content-type' => 'application/pdf')
);

// レスポンスヘッダーにContent-Dispositionをセットし、ファイル名をreceipt.pdfに指定
$response->headers->set('Content-Disposition', 'attachment; filename="receipt.pdf"');

return $response;
}

/**
* @return string
*/

private function getLibPath()
{
return realpath(sprintf('%s/../lib', $this->get('kernel')->getRootDir()));
}
}


これで、文字列が追加されたPDFが得られます。

もちろんこのまま $receipt->AddPage(); を続ければ、領収書をまとめてPDFとして出力することもできます。

以下のページを参考にさせていただきました :

TCPDFとFPDIの使い方メモ