コムセント 技術情報

  1. TOP
  2. コムセント 技術情報
  3. PHP+FPDI+TCPDFでPDFデータを処理する

PHP+FPDI+TCPDFでPDFデータを処理する

PHP上でPDFを処理する場合、「FPDI」及び「TCPDF」というライブラリを使用して行うケースが多いです。
主にFPDIではファイルの読み込みを、TCPDFではファイルの出力を行います。
これらライブラリには多くの機能がありますが、今回は内容を絞って
「PDFの読み込み→文字・画像の描画→データの出力」までを紹介します。

事前の諸注意

最初に注意すべき点として、PDFファイルは内部的にバージョン情報を持っていますが
FPDIはフリー版を利用する場合Ver1.5以上のPDFファイルを読み込む事ができません。
FPDIを利用してVer1.5以上のファイルを読み込みたい場合は、ライセンスを購入する必要があります。

以下のURLから読み込みのチェックが可能です。
https://www.setasign.com/products/fpdi-pdf-parser/details/

フリー版を利用する場合、例えば「事前に運営側がPDFをテンプレートとして用意しておく」…といった運用をするのであればバージョンの低いPDFを用意しておけば問題ありませんが、
ユーザーにPDFをアップロードしてもらう場合、当然バージョンが低いPDFを用意してくれるとは限らない・それを求めるのも大変という事で、PDFのバージョンをチェックする機能を用意する必要があります。
利用できないPDFがアップロードされた際、何か返り値があるわけではなく例外エラーを出力するので
try/catchなどを利用して判定機能を作成する必要があります。

余談として、PDFのバージョンを下げたい場合は

  1. adobe acrobat proでPDFを開く
  2. ファイルから「印刷」を選択
  3. プリンターを「Adobe PDF」に変更
  4. プロパティから「PDF設定」の「編集」を選ぶ
  5. Acrobat 4.0(PDF1.4)を選択
  6. 名前をつけて保存、印刷(PDFで出力)を行

という手順を組む事で可能です。

 

FPDIとTCPDFをロードして初期設定を行う

事前に設置したFPDIとTCPDFをPHP上で読み込みます。
zip版とcomposer版がありますので、好きな方を利用しましょう。

機能としては本当にたくさんあるのですが、
今回はPDF上に文章・画像を追加して書き出すまでに必要な最低限の設定を利用します。

まず初期設定として以下のコードを利用します。

コード機能
setSourceFile(string)利用するファイルを読み込む。
この時、無料版ではVer1.5以上のデータを利用するとエラーになるのでtry/catchで制御したい。
SetMargins(float,float,float)PDFページの上・左・右の余白を設定する。
指定しなかった場合は10mmとなる。
SetAutoPageBreak(boolean)自動改ページ機能のtrue/falseを判定する。これがtrueになっている場合、例えば最下段に文字を置いて自動改行が入った時に2ページ目にはみ出る。
setDisplayMode(mixed,string)PDFがビューア上でどのように表示されるかの設定を行う。それぞれ、
fullpage/fullwidth/real/default
(ページ全体表示/ウィンドウ幅に合わせる/実寸表示/ブラウザのデフォルト表示)
single/continuous/two/default
(PDFページを1枚ずつ表示/連続して表示 / 2列表示 / ブラウザのデフォルト表示)
を選択します。
setPrintHeader(boolean)PDFにデフォルトで存在するヘッダー余白を利用するか否か。
setPrintFooter(boolean)PDFにデフォルトで存在するフッター余白を利用するか否か。
setFontSubsetting(boolean)PDFファイルにフォントを埋め込むか否か。
設定を指定しなくても良い部分などは省いております

最低限の構成として以下のコードを貼り付けておけばひとまずの設定は終了です。
以下はコードの例です。





require_once('./pdf/tcpdf/tcpdf.php');//tcpdfの読み込み
require_once('./pdf/fpdi/fpdi.php'); //fpdiの読み込み
$this->pdf->SetMargins(0, 0, 0); //余白は0
$this->pdf->SetCellPadding(0); //余白は0
$this->pdf->SetAutoPageBreak(false) //最下段に置いた文章が2ページ目にはみ出るような状態でも、
                   勝手に改ページはしない
$this->pdf->setDisplayMode('default'); // 表示は標準
$this->pdf->setPrintHeader(false); //ヘッダーなし
$this->pdf->setPrintFooter(false); //フッターなし
$this->pdf->setFontSubsetting(true); // フォントは埋め込む

PDFの読み込み,描画

以下、実際にPDFにデータを記載していきます。

TCPDF+FPDIでPDFを作成する際、初期状態だと「0ページのPDF」が作られた状態となっています。
この「0ページのPDF」にページを追加し、文字を載せ、必要であれば既存のPDFを乗せる…という形でPDFを生成します。
そのため、まずAddPageによって「1ページ目」を作り、また必要であれば2ページ目以降を追加していく必要があります。

コード機能
setSourceFile(string)デフォルトで利用するPDFが存在する場合はこのメソッドで読み込む。
この時、取り扱えないPDFを読み込むとエラーを吐いて処理が終了するので注意。
返り値として、ページ数が入る。
AddPage()PDFページを追加する。
※上部に詳細を記載。
importPage(int)事前にsetSourceFileでPDFを読み込んでいると、importPageを利用して読み込んだPDFの特定ページを指定できる。
この下のuseTemplateと合わせて利用する。
useTemplate(string)useTemplateの引数としてimportPageを利用する事で、読み込んだPDFファイルをページに当てはめる事ができる。
例:$this->pdf->useTemplate($this->pdf->importPage(1))とすると、
  事前に読み込んだPDFの1ページ目を、これから生成するPDFの内容として
  追加することができる。
返り値としてwidthやheightなどpdfのデータが返される。
SetFont(string,string,float)使用するフォント、フォントスタイル(太字など)、文字サイズ(数字)を設定。
利用できるフォントスタイルはB/I/U/D/空文字。(ボールド・イタリック・アンダーライン・打ち消し線・なにもなし)
SetXY(float,float)Writeで書き込むX座標とY座標を設定する。以降SetXYが更新されない限り、全てのWriteがこの座標になる。
Write(float,string,string,bool,string
)
実際に文章を記述するための処理、
それぞれ、
行の高さ / 描画する文字 / リンクURL / 背景塗りつぶし設定 / テキスト揃え /
を設定する。
テキスト揃えはL/C/R/J(左/中央/右/両端)の5項目から選択する。
Output(string,string)PDFファイルを出力する。ファイル名とアウトプットの方法をI/D/F/S(ブラウザへの出力/ダウンロード/ローカルに保存/PDFファイルを文字列化して出力)で選択する。
設定を指定しなくても良い部分などは省いております

実際のフロー(サンプル)

これまでのコードで最低限のPDF書き出しが可能です。
以下、サンプルとして「PDFを読み込んでページ数を書き込んで出力する」というサンプルコードを記載します。

こちらも、勿論ただのPHPで動いているので
途中別のライブラリやメソッドからデータを引っ張ってきたり各種計算を挟む事ができます。
また、TCDPF+PDFIにはこれ以外にも多くの機能がありますので、色々試してみましょう。
require_once('./pdf/tcpdf/tcpdf.php');//tcpdfの読み込み
require_once('./pdf/fpdi/fpdi.php'); //fpdiの読み込み
$this->pdf->SetMargins(0, 0, 0); //余白は0
$this->pdf->SetCellPadding(0); //余白は0
$this->pdf->SetAutoPageBreak(false) //2ページ目の突入はなし
$this->pdf->setDisplayMode('default'); // 表示は標準
$this->pdf->setPrintHeader(false); //ヘッダーなし
$this->pdf->setPrintFooter(false); //フッターなし
$this->pdf->setFontSubsetting(true); // フォントは埋め込む

$pages  = $this->pdf->setSourceFile('ファイルURLを記載');//ファイルを読み込む。返り値でページ数を取得

$this->pdf->SetFont('kozminproregular', '', 12);// 日本語フォントを12pxでセットしておく

for ($i = 1; $i <= $pages ; $i++) {
  $this->pdf->AddPage();//「ページの追加」を行う
  $this->pdf->useTemplate($this->pdf->importPage($i)); //読み込んだファイルを実際にPDF上にインポートする。
$this->pdf->SetXY(intval($data['width'])/2, 210);//ページカウントの追加。中央・下部に追加する。
}
$this->pdf->Output('SAMPLE.pdf','D'); //データを出力する。

プログラマー/S.Y

このメンバーの記事一覧へ

おすすめ記事