LoginSignup
0
6

More than 3 years have passed since last update.

【PHP】TCPDF + FPDIでPDFを出力してみた話

Last updated at Posted at 2020-09-26

はじめに

タイトルの通りですが
TCPDFFPDIのライブラリを使用して、PDFを出力してみました。
今回はコマンドラインから実行してみます。

本編

環境構築

お好みでPHP、Composerが使用できる環境を用意してください。

Docker

今回私が使用したDocker環境は以下です(一部割愛)。

./docker-compose.yml
version: '3'
services:
 php:
   build: ./php
   volumes:
     - ./work:/home/work
./php/dockerfile
FROM php:7.3-fpm
COPY php.ini /usr/local/etc/php/

# Composer
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \
  && php -r "if (hash_file('sha384', 'composer-setup.php') === '795f976fe0ebd8b75f26a6dd68f78fd3453ce79f32ecb33e7fd087d39bfeb978342fb73ac986cd4f54edd0dc902601dc') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" \
  && php composer-setup.php \
  && php -r "unlink('composer-setup.php');" \
  && mv composer.phar /usr/local/bin/composer
./php/php.ini
date.timezone = "Asia/Tokyo"

Composer

立ち上げが完了したらphpのコンテナへ入り、
Composerでライブラリのインストールを行います。

また、ライブラリの他にautoloadの記載も追加しています。

/home/work/src/composer.json
{
    "require": {
        "setasign/fpdi": "^2.3",
        "tecnickcom/tcpdf": "^6.3"
    },

    "autoload": {
        "psr-4": {
            "Classes\\" : "classes/"
        }
    }
}

インストールが終われば完了です。

# cd /home/work/src
# composer install

実装

ファイル構成

# cd /home/work/

# ls /home/work/output/pdf/fileYYYYmmdd-HHiiss #PDF出力ファイル
# ls /home/work/src/resources/font/ipam.ttf #フォントの格納先
# ls /home/work/src/resources/pdf/templete.pdf #PDFテンプレートの格納先
# ls /home/work/bin/make-pdf.php #コマンドラインで実行するソース
# ls /home/work/src/bootstrap.php # 起動用ファイル(割愛)
# ls /home/work/src/classes/MyTcpdf.php # TCPDF利用クラス
# ls /home/work/src/classes/common/DynamicProperty.php # 動的クラス(割愛)
# ls /home/work/src/classes/MyTcpdf/FontColor.php # フォントカラークラス(割愛)

テンプレート

至ってシンプルなPDFテンプレートファイルです。

image.png

ソース

/home/work/bin/make-pdf.php
<?php

require_once __DIR__ . '/../src/bootstrap.php';

use Classes\MyTcpdf;
use Classes\MyTcpdf\FontColor;

// テンプレートを使用せずに出力
$myTcpdf = new MyTcpdf();
$myTcpdf->addPage();
$myTcpdf->setText('テンプレートを使用せずに出力', 10, 20, new FontColor(0, 255, 0));
$myTcpdf->outputPdfFile();

// テンプレートを使用して出力
$myTcpdfTmp = new MyTcpdf();
$myTcpdfTmp->addPageWithTemplete(1);
$myTcpdfTmp->setText('テンプレートを使用して出力', 10, 20, new FontColor(255, 0, 0));
$myTcpdfTmp->outputPdfFile();
/home/work/src/classes/MyTcpdf.php
<?php

namespace Classes;

use TCPDF_FONTS;
use setasign\Fpdi\Tcpdf\Fpdi;
use Classes\MyTcpdf\FontColor;

class MyTcpdf
{
    // 出力ファイル
    const OUTPUT_FORMAT_CHAR = 'F';
    const OUTPUT_FILE_DIR = __DIR__.'/../../output/pdf/';
    const OUTPUT_FILE_NAME = 'file';

    // PDF
    const PDF_ORIENTATION = 'P';
    const PDF_UNIT = 'mm';
    const PDF_SIZE = 'A4';
    const PDF_TEMPLETE = __DIR__.'/../resources/pdf/templete.pdf';

    // フォントファイル
    const FONT_FILE_NAME = __DIR__.'/../resources/font/ipam.ttf';

    /**
     * コンストラクタ
     */
    public function __construct()
    {
        $this->fpdi = new Fpdi(self::PDF_ORIENTATION, self::PDF_UNIT, self::PDF_SIZE);
        $this->fpdi->SetMargins(0, 0, 0);
        $this->fpdi->SetFont($this->getFont(), '', 32);
    }

    /**
     * 出力文字を設定する
     * @param _text 文字列
     * @param _x X座標
     * @param _y Y座標
     * @param _h 高さ
     */
    public function setText(string $_text, int $_x, int $_y, FontColor $_fontColor, int $_h = 0)
    {
        $this->fpdi->SetTextColor($_fontColor->R, $_fontColor->G, $_fontColor->B);
        $this->fpdi->SetXY($_x, $_y);
        $this->fpdi->Write($_h, $_text);
    }

    /**
     * 追加するフォントを取得する
     */
    private function getFont()
    {
        return TCPDF_FONTS::addTTFfont(self::FONT_FILE_NAME);
    }

    /**
     * 出力するファイル名を取得する
     * @return string ファイル名
     */
    private function getOutputFilename()
    {
        return self::OUTPUT_FILE_DIR . self::OUTPUT_FILE_NAME . date("Ymd-His"). '.pdf';
    }

    /**
     * ページを追加する
     */
    public function addPage()
    {
        $this->fpdi->AddPage();
    }

    /**
     * テンプレートベースのページを追加する
     */
    public function addPageWithTemplete($_pageNum)
    {
        $this->fpdi->SetSourceFile(self::PDF_TEMPLETE);
        $page = $this->fpdi->importPage($_pageNum);
        $this->fpdi->AddPage();
        $this->fpdi->useTemplate($page, null, null, null, null, true);
    }

    /**
     * PDFファイル出力
     */
    public function outputPdfFile()
    {
        $this->fpdi->Output(
            $this->getOutputFilename(),
            self::OUTPUT_FORMAT_CHAR
        );
    }
}

実行コマンド

php /home/work/bin/make-pdf.php

実行結果

以下のようにファイルが出力された。

テンプレートなし テンプレートあり
image.png image.png

終わりに

PDFのテンプレートの上に文字を出力できるので、フォーマットを変えずに必要な情報だけを出力できますね。
勤務表や請求書・領収書など、特定の部分だけが変動するファイルに活用できそう。

0
6
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
0
6