☆Yuus Memo☆
非エンジニアの方でも業務を効率化できるプログラムを紹介します!
PHP

【PHP】PDFで帳票出力

TCPDF

皆さんこんにちは!!
PHPでWebの業務システムを作っていると、必ず帳票(レポート類)を出力する処理が必要になります。

PHPで帳票を作成する処理は、結構面倒で私もあまり好きではありません。
専用の帳票ライブラリーを使用すると簡単なのかもしれませんが、高額なものが多く、私は使用したことがありません。

PHPで帳票を出力する手段として次のものが一般的です。

  • Excel出力
  • PDF出力
  • HTMLとCSSで印刷レイアウトを作る

Excel出力は以前記事に書いてあるので、目を通してください。

Laravel+VueでTrello Cloneを作ろう
PHPからExcel出力 いつも当ブログをご覧いただき、誠にありがとうございます。最近は、暑くて不快な日が続いているので、皆さんも長くて頭を使う内容なんて読みた...

PDF出力と、HTML+CSSで印刷レイアウトを作る方法はどちらも一長一短がありますが、PDF出力は専用ライブラリを使用することで、簡単に帳票を作り込むことができるので、今回はPDF出力の方法を書いていきたいと思います。

TCPDF+FPDIの準備

PHPで使用できるPDFライブラリは、いくつか選択肢がありますが、独立したライブラリで、単独で高機能なPDFを利用できる「TCPDF」を今回は使用したいと思います。

FPDI(Free PDF Document Importer)は、既存のPDFファイルを読み込みテンプレートとして使用できるライブラリです。
TCPDFとセットで使用することで、既存のPDFテンプレートを利用し、DBなどから取得した値を書き込めるようになります。

※詳しくは下記公式サイトをご覧ください。

TCPDF+FPDIのダウンロード

Composerが必要になりますので、インストールができていない方は先にインストールしてください。
こちらの記事で、簡単にインストールの説明があります。

【XAMPP環境でLaravel入門:Windows10】(function(b,c,f,g,a,d,e){b.MoshimoAffiliateObject=a;b[a]=b[a]||funct...

まずルートディレクトリに適当なディレクトリを作成して、下記のコマンドをターミナル若くはコマンドプロンプトから実行してください。

composer require setasign/fpdi
composer require tecnickcom/tcpdf

これだけで、TCPDF+FPDIを使用する準備が整いました。

PHPからTCPDF+FPDIを使用してみる

基本的な使い方をまずは説明します。

まず、index.php(名前はなんでも良いです)を作成して、下記のコードを映してください。

<?php
declare(strict_types = 1);

require_once 'vendor/tecnickcom/tcpdf/tcpdf.php';
require_once 'vendor/setasign/fpdi/src/autoload.php';

use setasign\Fpdi\Tcpdf\Fpdi;

// 用紙の設定
$pdf = new Fpdi('P', 'mm', 'A4');
$pdf->AddPage();

// フォントの設定
$pdf->SetFont('Helvetica', '', 32);
$pdf->SetTextColor(255, 0, 0);
$pdf->SetXY(20, 30);
$pdf->Write(0, 'Hello, World!!');

// 出力
$pdf->Output();

Webブラウザーからアクセスしてプログラムを実行してみてください。
PDFがブラウザーに表示されたかと思います。
使い方を簡単に説明します。

FPDIオブジェクトの作成時には用紙方向(縦がP/横がL)、単位、用紙サイズを指定します。

$pdf = new Fpdi('P', 'mm', 'A4');

続いて、SetFont()メソッドでフォントを指定。その後、色や描画位置を指定し、Write()メソッドで文字を書き込みます。

簡単ですね!!
ただ、これだけでは日本語の印刷が出来なかったり、実用的な使い方が見えないと思いますので、もう少し使い方・設定をお伝えします。

TCPDF+FPDIを日本語に対応させる

TCPDF自体は日本語の出力にも対応しているのですが、日本語フォントを用意しないと出力できません。

プログラムファイルと同じディレクトリに「font」というディレクトリを作り、そこに「ipagp.ttf」というフォントファイルを入れてください。

日本語フォントの準備ができたら、phpファイルを作り次のコードを写してください。

<?php
declare(strict_types = 1);

require_once 'vendor/tecnickcom/tcpdf/tcpdf.php';
require_once 'vendor/setasign/fpdi/src/autoload.php';

use setasign\Fpdi\Tcpdf\Fpdi;

// 用紙設定
$pdf = new Fpdi('P', 'mm', 'A4');
$pdf->AddPage();

// 日本語フォントの設定
$fontPath = dirname(__FILE__) . '/font/ipagp.ttf';
$font = TCPDF_FONTS::addTTFfont($fontPath);
$pdf->SetFont($font, '', 32);

// 色と位置を指定して日本語を描画
$pdf->SetTextColor(30, 0, 90);
$pdf->SetXY(20, 30);
$pdf->Write(0, "皆さん、こんにちは!!");
$pdf->SetXY(20, 54);
$pdf->Write(0, "PHPから、日本語のPDFを生成しています。");

// 画面に出力
$pdf->Output();

Webブラウザーからアクセスしてプログラムを実行してみてください。
日本語で文章が表示できているかと思います。

ポイントは、addTTFfont()メソッドでTTFフォントを追加して、SetFont() メソッドで描画フォントを指定している次の部分です。

// 日本語フォントの設定
$fontPath = dirname(__FILE__) . '/font/ipagp.ttf';
$font = TCPDF_FONTS::addTTFfont($fontPath);
$pdf->SetFont($font, '', 32);

ここまで出来ると次は画像や図形を表示したくなりますよね?笑
画像や図形の表示も説明します。

TCPDF+FPDIで画像・図形を表示

画像を表示するのは簡単で、Image()メソッドを使用し、座標・サイズを指定するだけです。

<?php
declare(strict_types = 1);

require_once 'vendor/tecnickcom/tcpdf/tcpdf.php';
require_once 'vendor/setasign/fpdi/src/autoload.php';

use setasign\Fpdi\Tcpdf\Fpdi;

// 用紙設定
$pdf = new Fpdi('P', 'mm', 'A4');
$pdf->AddPage();

// 画像を描画
$r = 170 / 400;
$w = 300 * $r;
$h = 250 * $r;
$x = 20; $y = 50;
$pdf->Image('images/test.jpg', $x, $y, $w, $h, 'JPG');

// フォントの設定
$pdf->SetFont('Helvetica', '', 32);
$pdf->SetTextColor(0, 200, 0);
$pdf->SetXY(20, 30);
$pdf->Write(0, 'Image display test');

// 画面に出力
$pdf->Output();

図形もサイズや描画位置を指定してコードを書きます。

<?php
declare(strict_types = 1);

require_once 'vendor/tecnickcom/tcpdf/tcpdf.php';
require_once 'vendor/setasign/fpdi/src/autoload.php';

use setasign\Fpdi\Tcpdf\Fpdi;

// 用紙設定
$pdf = new Fpdi('P', 'mm', 'A4');
$pdf->AddPage();

// 紫の横線
// 線のスタイルを指定
$pdf->SetLineStyle([
    "width" => 3,
    "dash" => 0,
    "color" => [255, 0, 255]
]);

// 罫線を描画
$pdf->Line(10, 20, 190, 20);

// ドットで複数の線を描く
$pdf->SetLineStyle([
    "width" => 0.3,
    "dash" => 1,
]);

for ($i = 0; $i < 30; $i++) {
    $pdf->Line(10, 30, 190, 30 + $i * 2, ["color" => [255, 0, 0]]);
    $pdf->Line(10, 90, 190, 30 + $i * 2, ["color" => [0, 0, 255]]);
}

// いろいろな図形
$pdf->SetLineStyle([
    "width" => 1, "dash" => 0, "color" => [0, 0, 0]
]);
// 矩形を描画
$pdf->Rect(10, 100, 30, 30);
// 連続線を描画
$pdf->PolyLine([50, 100, 80, 120, 110, 100, 140, 120]);
// 円を描画
$pdf->Ellipse(170, 115, 15, 15);

// 画面に出力
$pdf->Output();

図形を描く時は、それぞれ専用のメソッドが用意されています。
これらのメソッドはTCPDFの機能になりFPDIは、その機能をラップしている形になります。

詳細な説明は、TCPDFの公式ドキュメントをご確認ください。

既存のPDFファイルにPHPから書き込む

ここまでの解説で、非常に便利にPDFファイルを扱えることが伝わっていると思いますが、実用的な例では無かったので、一つ実用的な使用方法を作ってみます。

すでにPDFでテンプレートが用意されていて、そのテンプレートに「宛名」「金額」「日付」「但し書き」をPHPから書き込むプログラムを作りたいと思います。

PDFを用意するのが面倒な方はお使いください。

<?php
declare(strict_types = 1);

require_once 'vendor/tecnickcom/tcpdf/tcpdf.php';
require_once 'vendor/setasign/fpdi/src/autoload.php';

use setasign\Fpdi\Tcpdf\Fpdi;

// 用紙設定
$pdf = new Fpdi('P', 'mm', 'A4');
$pdf->SetMargins(0, 0, 0);

// 基本情報
$templateFile = 'images/sample.pdf'; // 領収書テンプレートPDF
$fontPath = 'font/ipagp.ttf'; // 日本語表示の時に使ったTTFフォントファイル

// テンプレートの複製
$pdf->SetSourceFile($templateFile);
$p1 = $pdf->importPage(1);
$pdf->AddPage();
$pdf->useTemplate($p1, null, null, null, null, true);

// フォントの設定
$font = TCPDF_FONTS::addTTFfont($fontPath);
$pdf->SetFont($font, '', 28);
$pdf->SetTextColor(0, 0, 0);

// dummy data
$data = [
    "name"  => "山田 太郎",
    "price" => "¥9,990-",
    "desc" => "お食事代として",
    "y" => 2020, "m" => 11, "d" => 27
];

// 名前
$pdf->SetXY(90, 25);
$pdf->Write(0, $data["name"]);
// 金額
$pdf->SetXY(80, 45);
$pdf->Write(0, $data["price"]);
// 日付
$pdf->SetFont($font, '', 14);
$pdf->SetXY(38, 77);
$pdf->Write(0, $data["y"]);
$pdf->SetXY(64, 77);
$pdf->Write(0, $data["m"]);
$pdf->SetXY(86, 77);
$pdf->Write(0, $data["d"]);
// 但し書き
$pdf->SetXY(40, 62);
$pdf->Write(0, $data["desc"]);

// 画面に出力
$pdf->Output();

Webブラウザーで実行すると、正しくPDFにダミーデータが表示されたと思います。

このプログラムを応用することで、データベースの情報を利用した帳票が簡単に作れるかと思います。

また、UIを作成すれば、「帳票レイアウトツール」も作成可能です。

PDFをファイルに出力

今回作成したサンプルでは、全てブラウザーへ表示していましたが、ファイルへ出力することも可能です。

画面に出力している部分を下記のように変更してください。

// 画面に出力
//$pdf->Output();

// ファイルに出力
$filePath = dirname(__FILE__) . "test_file.pdf";
$pdf->Output($filePath, 'F');

Outputメソッドの第2引数へ「F」を渡すことで、ファイルへ出力できます。
ちなみにパラメータは以下のようになっています。

パラメータ意味
Fファイルへ保存
IWebブラウザーで表示
Dファイルとしてダウンロード
S文字列で返す
EBase64でエンコードしたものを返す
Outputメソッドの第2引数のパラメータ説明

まとめ

いかがでしたか?
業務アプリケーションを作成する場合、帳票は必ずついてきます。

今回、紹介させていただいたコードを応用することで、決められたフォーマットの帳票でも、1からプログラムで作る帳票でも対応可能かと思います。

微妙な座標の調整やサイズの調整など、面倒な部分は多いですが帳票のレイアウトは1度作成すると、大きく変わることは少ないので頑張って作ってください。

また、今回は長くなってしまったので紹介しませんでしたが、TCPDFではバーコードやQRコードの出力といった機能もあります。
こちらについては、応用編としてその内記事を書かせていただきます。

最後までお読みいただき、ありがとうございます!!


コメントを残す