SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ライセンス制限が緩く高速でPDFを作成可能なPHPライブラリ「Haru」

PHP::Haruで簡単なPDF帳票を作成する

ライセンス制限が緩く高速でPDFを作成可能なPHPライブラリ「Haru」(2)

  • X ポスト
  • このエントリーをはてなブックマークに追加

 次に各行を出力する共通関数としてdraw_row関数を定義します。

行の表示(code_layout.phpの一部)
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タグの右側のみボーダーを出力しているようなイメージです。

 また省略しましたが、数値の場合にはカラムで右寄せ、それ以外では左寄せのようにしております。そのために、実際に表示する文字列の横幅を計算し、実際に表示する位置を決めています(コード内の説明は、前回の「囲み文字を実現する」を参照してください)。

レイアウト処理

 ここまで作成した関数を利用し、以下のように実行することで配置していきます。

各行の出力処理(code_layout.phpの一部)
//  ページを追加
$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のエクステンション側の機能にはまだ実装されていませんが、今後も対応されていくと思います。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
ライセンス制限が緩く高速でPDFを作成可能なPHPライブラリ「Haru」連載記事一覧
この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7218 2013/06/28 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング