これは PHP Advent Calendar 2015 21日目の記事です。
Thinreports for PHP については、まだ alpha 版だったときに下記 Qiita エントリーでも紹介していましたが、先日 0.8.0 正式版をリリースしたので PHP7 でのサンプルコードや、alpha 版からの変更点などを含め、改めて紹介したいと思います。
Thinreports for PHP とは
まず、Thinreports (シンレポーツ)について説明する必要があります。
Thinreports
Thinreports は、2010年ごろオープンソースとしてリリースされた、Ruby 向けの帳票・PDFツールです。下記のような特徴があります。
- 国産 OSS
- レイアウトデザインツール Thinreports Editor と、レイアウトファイルを読み込んで PDF を生成する Ruby 向けライブラリ Thinreports Generator for Ruby がセット
詳しくは 公式サイト や下記 GitHub をご覧ください。
Thinreports for PHP
今回紹介する Thinreports for PHP は、この Thinreports における PDF 生成ライブラリの PHP 実装ということになります。もちろん、オープンソースとして開発が進められています。
下記のような特徴があります。
PDF 生成までの流れ
Thinreports は mPDF のような HTML to PDF ではなく、別のアプローチを採用しています。大まかには下記のような流れで PDF を生成します。
- デザインツール Thinreports Editor を使って帳票レイアウトファイルを作成
- レイアウト作成時に、値を埋め込みたいところに名前付きの領域(テキストボックスみたいなもの)を定義しておく
- 作成したレイアウトファイルを Thinreports for PHP で読み込んで、名前付きの領域に値を埋め込むなどして PDF を生成するコードを書く
Hello World
では実際にやってみます。今回はせっかくなので PHP7.0.1 で試してみます。Thinreports for PHP の README.md でも簡単に説明していますので、そちらも参考にしてください。
準備
PHP7.0.1 と Composer がインストールされていることが前提です。これらのインストール手順については割愛します。PHP については、サポートしている 5.3+ であれば問題ありません。
Step1. Thinreports Editor をインストール
Editor は Chrome アプリとして動作します。Google Chrome をインストールしていない場合はインストールしてください。Chrome の準備ができたら Chrome ウェブストア (無料)にアクセスして、右上の "CHROME に追加" をクリックすると Thinreports Editor がインストールできます。 このとき、 Google アカウントは必ずしも必要ではありません。
Step2. 帳票レイアウトファイルを作成
まず、Thinreports Editor を起動して、新規作成ボタンから新しいレポートを作成します。ここでは、用紙サイズや余白などはデフォルトのままとして OK をクリックします。
続いて、下記のようにテキストブロックを貼り付けて、フォントサイズを 48 にして、ID を hello_world としておきます。
保存ボタンを押すと、保存先を指定するダイアログが表示されるので、作成したレイアウトファイルを任意の場所に保存します。ここではデスクトップに hello_world ディレクトリを作成して、その中に layout.tlf という名前で保存したとします。つまり ~/Desktop/hello_world/layout.tlf に保存したことになります。
Step3. thinreports-php/thinreports-php のインストール
$ cd ~/Desktop/hello_world $ composer require thinreports-php/thinreports-php
Step4. PDF 生成コードを書く
以下の内容で ~/Desktop/hello_world/hello_world.php を作成します。
<?php require 'vendor/autoload.php'; $report = new Thinreports\Report('layout.tlf'); # 1st page $page = $report->addPage(); $page->item('hello_world')->setValue('Hello World'); # 2nd page $page = $report->addPage(); $page('hello_world')->setValue('Hello Thinreports') ->setStyle('color', '#ff0000'); $report->generate('hello_world.pdf');
Step5. 実行する
$ cd ~/Desktop/hello_world $ php hello_world.php
成功すると ~/Desktop/hello_world/hello_world.pdf に以下のような PDF ファイルが作成されます。
Quick Reference
この他にも色々なことができます。まだ公式リファレンスをまとめていないので、ここで逆引き形式の簡単なリファレンスをまとめておくことにします。
けい線や図形、テキストのスタイルを動的に操作する
Editor で描画した図形やテキストのスタイルを PHP で動的に変更することができます。
<?php // なんでも $page->item('any_object')->hide(); $page->item('any_object')->show(); $page->item('any_object')->setVisible(true); // 四角形, 楕円形, 線形 $page->item('rect_id')->setStyle('border_width', 1) ->setStyle('border_color', '#0000ff') ->setStyle('fill_color', '#ff0000') // テキスト, テキストブロック $page->item('text_id')->setStyles(array( 'color' => 'blue', 'align' => 'center', // left, center, right 'valign' => 'bottom' // top, center, bottom 'font_size' => 20, 'bold' => true, 'italic' => false, 'linethrough' => true, 'underline' => false ));
複数のレイアウトを組み合わせる
Editor で複数のレイアウトを作成し、それらを使って一つの PDF ファイルを作成することも可能です。例えば、表紙のレイアウト cover.tlf と内容のレイアウト body.tlf で表紙付きの PDF を作成する場合は以下のように書きます。
<?php # 内容のレイアウト body.tlf をデフォルトレイアウトとして指定 $report = new Thinreports\Report('body.tlf'); # 表紙のレイアウト cover.tlf でページを作成 $cover = $report->addPage('cover.tlf'); $cover('title')->setValue('Title'); # 内容のレイアウト body.tlf でページを作成 # `#addPage` の第一引数を省略した場合は、デフォルトレイアウトでページを作成する $body = $report->addPage(); $body('content')->setValue('何かの内容'); $report->generate('result.pdf');
PDF データを取得する
PDF ファイルを作るのではなく、PDF データを取得することができます。
<?php # : $report->generate(); # => PDF data
日本語を出力する
Thinreports は、標準で日本語出力に対応しているため、レイアウト作成時に日本語フォントを設定すれば正しく出力されます。
ただし、選択できる日本語フォントは IPAフォントのみであることに注意してください。現状、任意のフォントを指定することはできません。
以上です。その他にも
- ページ番号ツールのフォーマットを変更する
- ページ毎に、ページ数のカウントから除外する
- 空白のページを追加する
- 簡易書式の設定を動的に変更する
- 一覧表っぽいものを作る
など、まだまだいろいろな機能がありますが、これらについてはまた別の機会で紹介したいと思います。 本当は laravel で簡単な帳票アプリを作る方法を紹介したかったのですが。これについてもまた別の機会に。
最後に
いかがでしたでしょうか?PHP7 で実際に動かしたのは今回初めてだったのですが、ちゃんと動くようで安心しました(テストコードはもちろんパスしてる)。ぜひ、PHP7 と共に触っていただけると嬉しいです。不具合などは GitHub へどうぞ。
明日は nori0620 さんです。