次に各行を出力する共通関数としてdraw_row関数を定義します。
function draw_row($page,$font,$size_cols,$row,$x,$y,$line_h){ $font_size = $page->getCurrentFontSize(); $col_margin_x = 10; $char_space = $page->getCharSpace(); $cur_x = $x; $cur_y = $y; foreach($row as $idx => $col){ $col_w = $size_cols[$idx]; $out_text = encode($col); $col_x = $cur_x + $col_w; // <---- (1) $col_y = $cur_y - $line_h; // <---- (2) // 各カラムの右の線を引く $page->moveTo($col_x,$cur_y); $page->lineTo($col_x,$col_y); // <---- (3) $page->stroke(); // <---- (4) $page->beginText(); if(ctype_digit($col)){ // 数値項目は、右寄せで主力する // (省略) } else{ // (省略) } // テキストを出力する // (省略) $cur_x = $col_x; } }
(1)、(2)で表示するカラムの左上座標を計算しております。そして、(3)、(4)で右にボーダーの線を引いています。HTMLで言えば、tdタグの右側のみボーダーを出力しているようなイメージです。
また省略しましたが、数値の場合にはカラムで右寄せ、それ以外では左寄せのようにしております。そのために、実際に表示する文字列の横幅を計算し、実際に表示する位置を決めています(コード内の説明は、前回の「囲み文字を実現する」を参照してください)。
レイアウト処理
ここまで作成した関数を利用し、以下のように実行することで配置していきます。
// ページを追加 $page = $haru_doc->addPage(); // (省略) $h = $page->getHeight(); // <---- (1) $w = $page->getWidth(); // <---- (2) $x = mmToPx(10); // <---- (3) $y = mmToPx(20); // <---- (4) text_underline($page, $x, $h - $y, "交通費精算書"); <---- (5) $y = mmToPx(30); // <---- (6) $data = array(); $header = array('社員番号' => 50,'所属' => 70,'氏名' => 70); // <---- (7) $data[] = array('A20150511','開発部','日本 太郎'); // <---- (8) $cur_y = table($page,$font,$header,$data,$x,$h - $y); //<---- (9) // (省略)
まず、(1)と(2)でページ全体のサイズを取得します。次に、「交通費精算書」の文字を表示する位置を、$x=10mm、$y=20mmにします。そのために(3)、(4)でその計算を行い、(5)で表示を行います。
このときに、実際に表示する縦の位置は(1)で取得したサイズから(4)の値を引いたものなので、ご注意ください。これ以降も同様な計算を行い設定します。
また、テーブルレイアウトは縦、30mmの位置に配置しますので、PDF上の位置を(6)のように計算します。
次に表示するテーブルは50mm、70mm、70mmで表示します。ラベルとそれらのサイズを(7)のように設定します。
(8)でデータを設定します。上記例では1行しかありませんが、「詳細項目」のように複数指定すれば、自動的に複数行に表示されます。
(9)でテーブルを配置します。戻り値は、表示された結果の縦位置を返すようにしており、このテーブルからの相対位置で次の要素を配置できるようにします。
同様に他のテーブルについても、(6)から(9)までのように繰り返して出力していきます。
レイアウトをする上での注意事項
レイアウトを行う上で自動的にサイズが変わることはありませんので、座標位置を常に気にする必要があります。このため、位置の計算と描写処理で非常に冗長的になりやすくなります。
サンプルではコードを分かりやすくするために、意図的に冗長的に記述している部分もあります。HTMLと同様に、スタイル(枠線や文字の下線等)とデータの実体のように分けるとコードを共通化しやすくなります。
最後に
紹介しなかった機能もたくさんありますが、これまで紹介した内容を参考にすれば、リファレンスを読むことでもっといろいろなことができます。
特にHaruの強みとして挙げられるのは、PDFのセキュリティ設定(パスワードでのプロテクト処理や印刷制限など)や、文字に関する細かいデータを取得できることです。
ほかのライブラリでは、表示する文字によって計算した結果と出力した結果で位置が微妙に違うということもあります。しかし、Haruは正しく計算ができるため、サンプルで示したような帳票を出力する場合に、非常に有用なエクステンションだと言えるでしょう。
また、Haruの元となっているlibharuもまだバージョンアップが行われており、libharu 2.2では主にアノテーション周りが強化されており、2.3から部分的にUTF-8のサポートも始まっております。これらはHaru、つまりPHPのエクステンション側の機能にはまだ実装されていませんが、今後も対応されていくと思います。