C:blanc
投稿日
2022年06月01日
Blog PHP

PHPでPDFのテンプレートに文字を書き込んで請求書を作成する

  • このエントリーをはてなブックマークに追加

はじめに

PDFのテンプレートに名前や住所などを配置して、請求書を作ってみたいと思います。
テンプレートのPDFを読み取るには FPDI を使います。
読み取ったテンプレートPDFに文字を配置するには TCPDF を使います。

TCPDFとFPDIをインストール

まずは、Composer で TCPDF と FPDI をインストールします。

composer install
composer.json
{
    "require": {
        "setasign/fpdi": "^2.3",
        "tecnickcom/tcpdf": "^6.4"
    }
}

PHPコード

23行目〜では住所2や会社名が無い場合の位置を調整しています。
また実際は、名前が無い場合は会社名に御中を付ける、といった前処理をします。

下記で、生成したPDFファイルを同じ階層のdataフォルダに書き出します。
$pdf->Output($file, 'F');

テンプレートはAdobe Illustratorで作成しました。

以下、コード全文です。
PHP
<?php
require_once __DIR__ . '/vendor/tecnickcom/tcpdf/tcpdf.php';
require_once __DIR__ . '/vendor/setasign/fpdi/src/autoload.php';
use setasign\Fpdi\Tcpdf\Fpdi;

$invoice_number = 1;
$file = __DIR__ . '/data/' . $invoice_number . '.pdf';
$template = __DIR__ . '/template.pdf';

$data = [
'no' => '請求書番号: ' . $invoice_number, 
'date' => '請求書発行日: ' . date('Y年n月j日'), 
'user_id' => '会員No: 1',
'company' => '海山商事株式会社',
'name' => '名前太郎様',
'zip' => '〒100-0001',
'address1' => '東京都千代田区',
'address2' => '○○町1-1-1',
'product' => '商品名',
'price' => '¥ 9,800 -'
];

$margin = 7;
if ('' === $data['address2']) {
    $position_company = 66;
} else {
    $position_company = 73;
}
$position_name = $position_company + $margin;
$position_user_id = $position_name + $margin;
if ('' === $data['company']) {
    $position_name -= $margin;
    $position_user_id -= $margin;
}

$pdf = new setasign\Fpdi\Tcpdf\Fpdi('P', 'mm', 'A4');
$pdf->SetMargins(0, 0, 20);
$pdf->SetAutoPageBreak(false);
$pdf->setPrintHeader(false);
$pdf->setPrintFooter(false);
$pdf->SetTextColor(0, 0, 0);
$pdf->SetSourceFile($template);
$p1 = $pdf->importPage(1);
$pdf->AddPage();
$pdf->useTemplate($p1, null, null, null, null, true);

// 日付
$pdf->SetFont('kozgopromedium', '', 9);
$pdf->SetXY(0, 43);
$pdf->Write(0, $data['date'], '', FALSE, 'R');

// 請求書No
$pdf->SetFont('kozgopromedium', '', 9);
$pdf->SetXY(0, 50);
$pdf->Write(0, $data['no'], '', FALSE, 'R');

// 住所
$pdf->SetFont('kozgopromedium', '', 10);
$pdf->SetXY(23, 52);
$pdf->Write(0, $data['zip']);

$pdf->SetFont('kozgopromedium', '', 10);
$pdf->SetXY(23, 58);
$pdf->Write(0, $data['address1']);

$pdf->SetFont('kozgopromedium', '', 10);
$pdf->SetXY(23, 64);
$pdf->Write(0, $data['address2']);

// 会社名
$pdf->SetFont('kozgopromedium', '', 12);
$pdf->SetXY(23, $position_company);
$pdf->Write(0, $data['company']);

// 名前
$pdf->SetFont('kozgopromedium', '', 12);
$pdf->SetXY(23, $position_name);
$pdf->Write(0, $data['name']);

// 会員No
$pdf->SetFont('kozgopromedium', '', 8);
$pdf->SetXY(23, $position_user_id);
$pdf->Write(0, $data['user_id']);

// 商品名
$pdf->SetFont('kozminproregular', '', 12);
$pdf->SetXY(53, 122.5);
$pdf->Write(0, $data['product']);

// 金額
$pdf->SetFont('kozminproregular', '', 22);
$pdf->SetXY(53, 134);
$pdf->Write(0, $data['price']);

$pdf->Output($file, 'F');

完成品

終わりに

「締め日に大量の請求書を送らなければならない」といった時、cronでPDFを自動生成し、メールに添付して送信する、といった使い方ができます。

あと、デフォルト以外のフォントに変えたり、表組みにしたりといろいろやりたいのですが、今回は見送りました。

PROFILE

C:blanc
フリーランスのプログラマーです。
  • COMMENT

    送信しました! コメントは承認後表示されます!
  • あと150文字