はじめに
タイトルの通りですが
TCPDFとFPDIのライブラリを使用して、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テンプレートファイルです。
ソース
/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
実行結果
以下のようにファイルが出力された。
テンプレートなし | テンプレートあり |
---|---|
![]() |
![]() |
終わりに
PDFのテンプレートの上に文字を出力できるので、フォーマットを変えずに必要な情報だけを出力できますね。
勤務表や請求書・領収書など、特定の部分だけが変動するファイルに活用できそう。