1
1

More than 1 year has passed since last update.

PHPでPDFに文言の埋め込みをする方法を試す

Posted at

はじめに

PDFを作成する方法の1つとして、以下の方法を試してみました。

  • ひな形PDFを用意する
  • 空欄に文言を埋め込んで最終形のPDFにする

サンプルとして中央区の申請書を利用しています。

↑から取得したPDFがこちら。
このPDFの空欄に文言を埋め込みました。

image.png

前提事項

  • 環境
    • Windows 10
    • PHP 7.4.28
    • Composer 2.4.4

成果物

完成したものがこちら。ソースは詳細の方を参照ください。
ひな形のPDFに赤字で文言を埋め込むことができました。

  • 良い点
    • 空欄に文言を埋め込むだけで良いのは楽
    • レイアウトと中身が分離できる=分担しやすい
    • 作成速度は速い
  • 悪い点
    • 位置合わせが大変
    • フォントサイズの調整が大変

↑個人的な感想です。

image.png

詳細

作成の経過を以下に記載しておきます。

方式検討

下記の参考サイトをもとに
・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

ブラウザで表示した結果がこちら。

image.png

文言を埋め込む

文言の埋め込み位置の指定が横(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);

ブラウザで表示した結果がこちら。

image.png

埋め込み完了

埋め込み情報をパラメータで渡すように変更。
本人が住民票の写しを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);

ブラウザで表示した結果がこちら。

image.png

以上で完了。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1