はじめに
PDFを作成する方法の1つとして、以下の方法を試してみました。
- ひな形PDFを用意する
- 空欄に文言を埋め込んで最終形のPDFにする
サンプルとして中央区の申請書を利用しています。
↑から取得したPDFがこちら。
このPDFの空欄に文言を埋め込みました。
前提事項
- 環境
- Windows 10
- PHP 7.4.28
- Composer 2.4.4
成果物
完成したものがこちら。ソースは詳細の方を参照ください。
ひな形のPDFに赤字で文言を埋め込むことができました。
- 良い点
- 空欄に文言を埋め込むだけで良いのは楽
- レイアウトと中身が分離できる=分担しやすい
- 作成速度は速い
- 悪い点
- 位置合わせが大変
- フォントサイズの調整が大変
↑個人的な感想です。
詳細
作成の経過を以下に記載しておきます。
方式検討
下記の参考サイトをもとに
・TCPDF
・FPDI
の2つのライブラリを利用してPDFを作成することにしました。
そのままですが、手順としてはこれだけです。
①FPDIでひな形のPDFを読み込む
②横(x)と縦(y)の位置を指定して文言を埋め込む
③結果のPDFを画面に出力する
準備
作業ディレクトリを作成し、composerで2つのライブラリを取得。
TCPDFを取得する
composer require tecnickcom/tcpdf
C:\donraq\php-sample-pdf>composer require tecnickcom/tcpdf
Info from https://repo.packagist.org: #StandWithUkraine
Using version ^6.6 for tecnickcom/tcpdf
./composer.json has been created
Running composer update tecnickcom/tcpdf
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking tecnickcom/tcpdf (6.6.0)
...途中省略
Generating autoload files
1 package you are using is looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found
FPDIを取得する
composer require setasign/fpdi
C:\donraq\php-sample-pdf>composer require setasign/fpdi
Using version ^2.3 for setasign/fpdi
./composer.json has been updated
Running composer update setasign/fpdi
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking setasign/fpdi (v2.3.6)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing setasign/fpdi (v2.3.6): Extracting archive
1 package suggestions were added by new dependencies, use `composer suggest` to see details.Generating autoload files
2 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
No security vulnerability advisories found
取得後の状態を確認する
C:\donraq\php-sample-pdf>tree
Folder PATH listing for volume OS
Volume serial number is 4EB4-CF59
C:.
└───vendor
├───composer
├───setasign
│ └───fpdi
│ └───src
│ ├───PdfParser
│ │ ├───CrossReference
│ │ ├───Filter
│ │ └───Type
│ ├───PdfReader
│ │ └───DataStructure
│ ├───Tcpdf
│ └───Tfpdf
└───tecnickcom
└───tcpdf
├───config
├───examples
│ ├───barcodes
│ ├───config
│ ├───data
│ │ └───cert
│ ├───images
│ └───lang
├───fonts
│ ├───ae_fonts_2.0
│ ├───dejavu-fonts-ttf-2.33
│ ├───dejavu-fonts-ttf-2.34
│ ├───freefont-20100919
│ └───freefont-20120503
├───include
│ └───barcodes
└───tools
ひな形PDFを配置する
C:\donraq\php-sample-pdf>dir
Volume in drive C is OS
Volume Serial Number is 4EB4-CF59
Directory of C:\donraq\php-sample-pdf
2022/12/11 22:23 <DIR> .
2022/12/11 22:23 <DIR> ..
2022/12/11 22:27 95 composer.json
2022/12/11 22:27 6,255 composer.lock
2022/12/11 10:54 118,025 jyuuminhyounihonnjin.pdf ★これ
2022/12/11 22:27 <DIR> vendor
3 File(s) 124,375 bytes
ひな形PDFを読み込んで表示してみる
ソースがこちら。
<?php
require_once('./vendor/autoload.php');
function outputPDF($path_tmpl_pdf) {
$fpdi = new setasign\Fpdi\Tcpdf\Fpdi();
// ひな形PDFの1ページ目を取り込む
$fpdi->setSourceFile($path_tmpl_pdf);
$tpl = $fpdi->importPage(1);
// 取り込んだひな形をPDFに反映
$fpdi->setPrintHeader(false);
$fpdi->AddPage();
$fpdi->useTemplate($tpl);
// PDFを画面に出力
$fpdi->Output("output.pdf", "I");
}
$path_tmpl_pdf = "/donraq/php-sample-pdf/jyuuminhyounihonnjin.pdf";
outputPDF($path_tmpl_pdf);
簡易サーバを立ち上げて。。。
php -S localhost:8030
ブラウザで表示した結果がこちら。
文言を埋め込む
文言の埋め込み位置の指定が横(x)と縦(y)の指定なので、結構面倒。
ここは位置を微調整していくしかない。
位置決めのガイドとして座標を全面に配置。
例)15-1 = x:150 y:10 という意味。
フォントは以下の2つが使用可能。
・kozgopromedium
・kozminproregular
※別途フォントのデータを組み込めば他のフォントを使うことも可能
ガイドを参考にして、いくつかの文言を配置したソースがこちら。
<?php
require_once('./vendor/autoload.php');
function outputPDF($path_tmpl_pdf) {
$fpdi = new setasign\Fpdi\Tcpdf\Fpdi();
// ひな形PDFの1ページ目を取り込む
$fpdi->setSourceFile($path_tmpl_pdf);
$tpl = $fpdi->importPage(1);
// 取り込んだひな形をPDFに反映
$fpdi->setPrintHeader(false);
$fpdi->AddPage();
$fpdi->useTemplate($tpl);
// フォントを指定 ※日本語表示するためには指定が必須
$fpdi->SetFont('kozgopromedium', '', 12);
$fpdi->setTextColor(255, 0, 0); // 色はわかりやすいように赤
// 住所
$fpdi->Text(60, 35, "○○○○○○町 100-1");
// 氏名
$fpdi->Text(40, 45, "シナガワ タロウ");
$fpdi->Text(40, 51, "品川 太郎");
// 位置決め用の座標を表示
$fpdi->SetFont('kozgopromedium', '', 7);
$fpdi->setTextColor(255, 160, 160);
for ($x = 0; $x <= 20; $x++) {
for ($y = 0; $y <= 27; $y++) {
$fpdi->Text($x * 10, $y * 10, "$x-$y");
}
}
// PDFを画面に出力
$fpdi->Output("output.pdf", "I");
}
$path_tmpl_pdf = "/donraq/php-sample-pdf/jyuuminhyounihonnjin.pdf";
outputPDF($path_tmpl_pdf);
ブラウザで表示した結果がこちら。
埋め込み完了
埋め込み情報をパラメータで渡すように変更。
本人が住民票の写しを1通、目的は運転免許証でとるという設定で埋め込み。
<?php
require_once('./vendor/autoload.php');
function outputEmbededPDF($path_tmpl_pdf, $embed_items) {
$fpdi = new setasign\Fpdi\Tcpdf\Fpdi();
// ひな形PDFの1ページ目を取り込む
$fpdi->setSourceFile($path_tmpl_pdf);
$tpl = $fpdi->importPage(1);
// 取り込んだひな形をPDFに反映
$fpdi->setPrintHeader(false);
$fpdi->AddPage();
$fpdi->useTemplate($tpl);
// フォントを指定
$fpdi->SetFont('kozgopromedium', '', 12);
$fpdi->setTextColor(255, 0, 0); // 色はわかりやすいように赤
// 項目の埋め込み
foreach ($embed_items as $key => $value) {
$pos = explode(",", $key);
$fpdi->Text($pos[0], $pos[1], $value);
}
// // 位置決め用の座標を表示
// $fpdi->SetFont('kozgopromedium', '', 7);
// $fpdi->setTextColor(255, 160, 160);
// for ($x = 0; $x <= 20; $x++) {
// for ($y = 0; $y <= 27; $y++) {
// $fpdi->Text($x * 10, $y * 10, "$x-$y");
// }
// }
// PDFを画面に出力
$fpdi->Output("output.pdf", "I");
}
$path_tmpl_pdf = "/donraq/php-sample-pdf/jyuuminhyounihonnjin.pdf";
$embed_items = [
"150,26" => "2022",
"167,26" => "12",
"178,26" => "12",
"60,35" => "○○○○○○町 100-1",
"40,45" => "シナガワ タロウ",
"40,51" => "品川 太郎",
"138,51" => "1900",
"158,51" => "01",
"172,51" => "01",
"37,62" => "✓",
"102,59" => "1",
"16,119" => "✓",
"16,177" => "✓",
"14,212" => "✓",
];
outputEmbededPDF($path_tmpl_pdf, $embed_items);
ブラウザで表示した結果がこちら。
以上で完了。