システム奮闘記:その55

FPDFでPDF帳票システム構築



Tweet

(2006年12月9日に掲載)
はじめに

  PDFファイルの作成。
  文書に使えるし、カタログに使えるし、見積書などにも使える。
  しかも、エクセルなどで画像を張り付けると重たいファイルになるのだが、
PDFファイルだと結構軽いので、メールで添付するには便利だ。

  それにAcrobatReaderを使えば、Windowsでも、Macでも、UNIX系でも
無料で閲覧ができるので、普及は進むはずのも納得ができる。

  だが、PDFファイルの作成となれば、費用がかかる。
  今回は、無料でPDFファイルの作成の話を書く事にしました。


PDF帳票ソフトを探す。PDFLibを発見するが・・・

PDFファイルの生成。 Windowsの場合だと、Adobeから出ているAcrobatが有名だ。 これを使うと、ワードやエクセルで作成した資料をPDFに変換できるため 相手のパソコンにエクセル、ワードが入っていない場合でも、 AcrobatReaderさえ入れれば、閲覧する事ができる。 なので、うちの会社でも2002年ぐらいに購入した。 (さすがに、だいぶ前なので記憶が定かではないが・・・) だが、ソフトの購入すると必ず費用が発生する。 そこで、無料でできる方法はないかと考えていた。 そんな中、有償だが Linux + Apache + PHP の仕組みを使えば、 PDFファイルの作成ができる事を、2003年に知った。 以下の本で知った。 「PHP4徹底攻略」(堀田倫英・石井達夫・廣川 類:ソフトバンクパブリッシング) 通称、マンモス本と呼ばれる本だ。 PDFlibを使えば、PHPと連携させて、PDFファイルの生成ができるのだ。 早速、PDFlibのサイトを見てみる事にした。 http://pdflib.jp/ 値段を見たら・・・ とても稟議が降りそうにない・・・ 費用対効果が示せれば、稟議が降りるかもしれないが、 単に「PDFファイルが生成できます」だけだったら、稟議なんぞ降りない。 だが、お試し版という形でPDFlibは使う事は可能だ。 もちろん、購入しないと、PDFlibのロゴの「羽のマーク」がついたままだが お試し版では気にならない。 どんな活用方法があるのか知るために、早速、試しに使ってみる事にした。 文字以外にも画像が取り込める。 カタログ作成に使えるのではないかと考え、サンプルプログラムを作った。 社内の反応は 何かに使えるんとちゃうかなぁ だったが、あまり乗り気ではなかった。 カタログ作成なら、わざわざWeb上で作成しなくても、エクセルやワードで 作成した後、PDFファイルに変換したら済むだけに、積極的に使う利点がない。 しかも、費用がかかるため、費用対効果が見えないため、 PDFlibの導入は、お蔵入りになった。
TeXでPDF帳票の方法を見つけるが・・・ 2004年の暮れ、書店で次の本を見つける。 「TeX + PHP + データベースによる PDF自動生成サーバーの構築/運用」 (ミッチー@rootbox:技術評論社) これは無料で使える! と思った。 実は、この本では軽くFPDFの事が触れられているのだが、 TeX を元にして、PDFの生成だという頭があったので、その部分を すっかり見落としていたのらー!! 見落としに気づいたのは、この奮闘記を編集している時で、 本をパラパラとめくっていると、FPDFの記述がある事に気づいたのだった (^^;; 不幸にして、FPDFの記述箇所を見落とした私。 なので、必死になって、TeXを使って、PDFに変換する事に取り組むのだが TeXなんぞ、すっかり忘れたぞ! だった。 大学時代、レポートや卒論などでTeXを使った事はある。 本を見ながら、タグを使って編集したのを覚えているのだが、 長い間、触っていないため、100%、忘れてしまったのだ。 それでも、なんとか、簡単な文章をTeXで書いたのだが、 生成された dviファイルで、日本語が表示できない上、 PDFへの変換もうまくいかなかった。 だが、意地になってでも、完成させようとは思わなかった。 なぜなら・・・ 必要に迫られていないからだ そのため、あっさりと挫折してしまった (--;;

無料のPDF生成ソフト・FPDFとの出会い。そして導入

それから月日が流れた。 そして2006年6月になり、PHPの勉強をしている際に、FPDFの存在を知る。 PHPのプログラムで、無料でPDFファイルを生成するツールだ。 PHP4以上で動く。 もしかして、使えるかも と思った。 そして、googleで「FPDF」を検索してみると以下のサイトを見つける。 「FPDFファンの集い処」 http://fpdf.japansite.net/ 日本語のマニュアルがあるので、早速、ダウンロード。 Web型式のマニュアルだ。 マニュアルを見て思った。 これは使えるぞ! 早速、FPDFをダウンロードして触ってみる事にした。 特に、ライブラリ依存の問題もないようだ。 PHPのコンパイルに、特に、FPDFのためのオプションをつける必要もない。 FPDFのソフトの導入は簡単だ。 FPDFをダウンロードする。そして展開する。 FPDFのファイルを置くディレクトリーは、PDFを出力させるPHPソースを置く ディレクトリと同じ場所にすればOKだ! PDFを出力させるPHPのソースは、以下のように使う。
こんな感じでFPDFを使う
<?php
require('fpdf.php');

(ここから先は、FPDFの関数を使って処理)
?>

  FPDFを使うための、難しい設定を行う必要はないのだ。


  だが、このままだと日本語が使えない。文字化けするからだ。
  でも、大丈夫。幸いな事に、日本語のパッチも用意されている。

  2種類のパッチがある。
  「FPDF_japanese」と「MBFPDF」だ。

  私は、「FPDF_japanese」を使った。
  特に考えて選んだというわけではなかった。
  単に、とりあえず、こっちから使ってみようという感じだった。

  日本語パッチ(FPDF_japanese)を以下のサイトからダウンロードした。
  http://www.fpdf.org/phorum/read.php?f=1&i=7977&t=7977


  japanese.php というソースがパッチだ。パッチといっても難しくはない。
  単に、fpdf.phpのファイルと同じディレクトリに保管すれば良いだけの事だ。

  (注意)
  日本語パッチ(FPDF_japanese)の場合、日本語の文字コードは
SJISのみ対応なので、日本語の部分をSJISにする必要がある。


  そして、PDF生成プログラム内で、require()で取り込むのを
fpdf.php から、japanese.phpに変更すれば良いのだ。

  こんな感じだ。

こんな感じで日本語パッチを経由でFPDFを使う
<?php
require('japanese.php');

(ここから先は、FPDFの関数を使って処理)
?>

  もちろん、japanese.phpは、fpdf.phpのソースに依存しているため、
japanese.php 単独では動かない。


  ところで、fpdf.phpは、PHP言語が書かれている。
  読者の中には「どれくらいソースの中身を解読しているの」という声が
あるかもしれませんが、今回は

  全く解読していませーん (^^)

  言い訳として「最近のシステム奮闘記はマニアック」という声を反映して、
難易度を下げたと言ってみたいのだが、そんな言い訳は、すぐにバレるので
正直な事を書きます。

  ソースの解読ができるように、PDFの事を勉強しようと考え
書店で「PDFリファレンス第2版」を見たのだが・・・

  ソースを読む気が失せました (--;;

  そうなのです。事務員なので、技術的に難しい事は、すぐに挫折します。
  というわけで、今回は、ソースの利用者に徹しました。
  (長い言い訳だなぁ・・・)


  早速、マニュアルを見ながら、みようみまねで作ってみた。

試作プログラム ( test1.php )
<?php
require('japanese.php');

$pdf=new PDF_Japanese();
$pdf->FPDF(Portrait ,mm,A4);
$pdf->AddSJISFont();
$pdf->Open();
$pdf->AddPage();
$pdf->SetFont('SJIS','',18);
$pdf->Write(8,'テストだよ〜ん');
$pdf->Output();
?>

  このソースの日本語の文字コードをSJISにした。

  結果は・・・

  文字化けする (TT)

  「なんでやねん」と思った。
  文字コードがSJISだから、問題ないはずやし・・・。

  考えた挙げ句、ふと思った。
  ソースだけでなく、内部処理コードもSJISにする必要があるかも。
  そこで、PHPのスプリプトを処理する際の、

日本語の出力をできるようにしてみた
<?php
require('japanese.php');

mb_internal_encoding('SJIS');

$pdf=new PDF_Japanese();
$pdf->AddSJISFont();
$pdf->Open();
$pdf->AddPage();
$pdf->SetFont('SJIS','',18);
$pdf->Write(8,'テストだよ〜ん');
$pdf->Output();
?>
青い部分が内部処理コードをSJISに指定する命令だ。
もちろん、/usr/local/lib/php.iniでも設定は可能だが、
上の場合のように、個々のソースでの設定もできるので、
この方が小回りは効く。

  再度、実験を行う。すると・・・

  見事、成功! (^^)V

  さて、内部処理コードをSJISにすれば、わざわざソースまで
SJISにする必要がないと考え、ソースコードはEUCにした。

  すると・・・

  文字化けしてしまうやん (^^;;

  だった。

  どうやら、PDFで出力するための日本語の部分の文字コードと、
内部処理のコードをSJISにする必要がある。

内部処理のコードをSJISにする必要はあるのか
実は、この編集している時に、別のマシンでPDFファイルの出力を
テストで行ってみた。
この時、わざと「mb_internal_encoding('SJIS');」を省いてみたが
問題なく日本語が表示できた。

今だに謎なのだが、私は、この命令をいれておく事にした。
いわば、安心料というつもりなのだが、キチンとした知識がなく
ただ、当てずっぽでやるのも、良い事とは思えない。
キチンと検証を行うべきなのだが、そこまでできる程の
実力がないのだが残念だ・・・

  さて、PDFの型式の設定方法を知るため、マニュアルをみていく事にした。

コードの説明
1:  <?php
2:  require('japanese.php');
3:
4:  mb_internal_encoding('SJIS');
5:
6:  $pdf=new PDF_Japanese();
7:  $pdf->AddSJISFont();
8:  $pdf->Open();
9:  $pdf->AddPage();
10: $pdf->SetFont('SJIS','',18);
11: $pdf->Write(8,'テストだよ〜ん');
12: $pdf->Output();
13: ?>
6行目は、PDFを出力させるためのクラス「PDF_Japanese()」を使った
オブジェクト「$pdf」を宣言する。
このオブジェクトの中にある関数で、線を引いたり、枠を囲んだりする。

7行目は、フォントの設定ファイルの指定のようだが、
普通は、特に何もしなくても良いみたい。

8行目は、PDFドキュメントの生成を開始の合図です。
9行目は、ページの開始。改ページを行う時も同じ命令を使います。
10行目は、フォントの設定。SJISと文字の大きさが18という意味。
11行目は、文字例の表示の命令
12行目は、PDFファイルの出力を行う

  あまり難しくない。

  以前の私なら「オブジェクト」と出ると、目が点になったが、
PHPの勉強や、Pukiwikiのコードを読む際に、オブジェクトの使い方を
なんとか理解したので、恐くない。

  マニュアルを見ながら、枠の作り方、線の引き方などを覚えた。


  だが、無料でPFDファイルを生成する事ができても、
何に使えるのか見えてこない。

  この時、AS400とLinuxとの連動ができなかったため、AS400のデータを
活用したPDFの帳票作成も考えられない。
  だが、PostgreSQLに入っているデータで帳票作成をする物もない。

  全く良い使い道が思いつかないため、社内に提案してみたが・・・

  反応があらへんかった (^^;;

  そう、使い道が思いつかないのだ。
  エクセル、ワードのデータなら、Acrobatなどのソフトが出回っている上、

  そのまま、お蔵入りになると思われた。

FPDFでPDF帳票システム構築の機会がやってくる!

だが、転機はすぐに訪れた。 2006年10月に、基幹システムのAS400を新しく買い替えた。 この年の6月にAS400とLinuxとの連動で、ODBC接続を行ったが断念した。 詳しくは「システム奮闘記:その51」(ODBC経由でAS400とLinuxの連動。でも断念)を、 ご覧になってください。 だが、新しいAS400の中に、SQL開発キットのお試し版が入っていたので、 unixODBCを使って、ODBC接続できるのではないかと考えた。
ODBC接続を使ったAS400とLinuxの連動実験
ODBCを使ったAS400とLinuxの連動
PHPのODBC関数を使ってAS400のデータベース(DB2)に
接続する事を考えた。

  見事の成功した!!

  だった。

  LinuxとAS400との連動の方法に関しては「システム奮闘記:その56」
iSeriesAccessを活用したODBC経由でAS400(iSeries,i5)とLinuxの連動に成功を
ご覧になってください (^^)


  ここで思った。
  基幹システムのAS400との連動が可能なので

  PDFで帳票ファイルが作成ができる!

  つまり以下の図のような形で、基幹システムのAS400の中にある
各種データを活用して、PDF帳票が作成できるのだ。

AS400とLinuxの連動によるPDF帳票出力システム
AS400とLinuxの連動を利用したPDF帳票システム

  ところで、AS400とLinuxを連動させなくても、応用用紙を使った
帳票印刷はできるし、実際に印刷をしている。

  だが、役員の中には「エクセルで欲しい。パソコン上で見たい」という声あり、
上司が、AS400上のデータを、CVSファイルでパソコン上に落とし込んで、
エクセルに加工していた。

  もちろん、AS400のデータを読み込んで、欲しい形に加工して
エクセルに落とし込む商用ソフトはある。
  だが、過去に何度か稟議を挙げても却下されるばかりだった。
  そのため、月初には、前月の実績関係のエクセル帳票作成のため、
上司は、丸1日費していた。

  なので、PDFファイルで帳票作成できれば、データの集計などは
プログラムが行ってくれるため、ボタン一つで帳票作成できる。
  上司の負担が軽くなると考えた。


  だが、この場合でも、SQL開発キットの予算を通さないといけない。
  いくらAS400のデータを加工して出力するソフトに比べて安くても
上層部が納得できる費用対効果がある事を示さないと稟議は通らない。


  そこで、毎月、上司が作成している帳票の1部を作成するプログラムを作って、
それから出力された帳票を試作品として示す事にした。

  試作品の作成を行った。
  エクセル帳票は、A4サイズなので、以下のような初期設定にした。

初期設定の部分
require('japanese.php');

mb_internal_encoding('SJIS');

$pdf=new PDF_Japanese();
$pdf->FPDF(Portrait ,mm,A4);
$pdf->AddSJISFont();
$pdf->Open();
$pdf->AddPage();
$pdf->SetFont('SJIS','',18);
今までのサンプルでは、赤い部分がありませんでした。
それは、そんな命令があるとは気がつかなかったためです。

この命令は、縦横の向き、長さの単位、用紙のサイズを指定する。
縦横の指定だが「Portrait」は縦向き、「Landscape」は横向きを意味する。
長さの単位だが「mm」はミリ単位だ。これだと定規で測りやすい。
紙のサイズだが「A4」はA4サイズ。A3、A5、Letter、Legalも指定できる

もし、この命令を省いた場合は、初期設定では、
縦長で、座標の位置はミリ単位で、A4サイズの用紙という設定になる。

ただ、省ける命令のようだが、省かず、入れておくのが無難だ。

  デカデカと帳票の題名を書くために、フォントのサイズを18にした。


  さて、枠組みと文字表示だが、以下の関数を使う。

枠組みと文字表示の関数
$pdf->Rect( 136 ,35 ,12 ,5);
$pdf->Text( 137 , 39  , "出力だよ!" );
$pdfはオブジェクトだ。

Rect()関数は枠組みを表示させる関数で使い方は以下の通りだ。
Rect( 横の座標の始点 , 縦の座標の始点 , 横の長さ , 縦の長さ )

Text()関数は、文字を表示させる関数だ。使い方は以下の通りだ。
Text( 文字の開始の横の始点の座標 , 文字の開始の縦の始点の座標 )

  さて、FPDFで、日本語パッチ(FPDF_japanese)を使う場合、
日本語の文字コードはSJISのみ対応になる。
  そのため、PHPのコードもSJISになるのだが、つまらんこだわりが出る。

  Linux上だからコードはEUCじゃないとイヤ!

  あくまでも、Linux上にあるPHPのソースコードは、EUCにこだわる私。
  なので、このワガママ(?)を満たすべく、以下のユーザー独自関数を作った。

文字コードを変換するための簡易関数
function toSjis ( $moji )
{
$mojicode = mb_detect_encoding($moji);
$moji2 =  mb_convert_encoding($moji,"SJIS",$mojicode);

return $moji2 ;
}

  大した関数ではないが、これだと私の欲求が満たされる。ウフフフ。

  だが、喜んでいたののも束の間だった。

  「PHPのソースはEUCに限る」という、くらだんこだわりをすると、
文字表示のトラブルが起こる。

  文字コードの変換を行っても、一部の文字で文字化けを起こす。

  例えば、次の例がある。

文字化けの具体例
$pdf->Rect( 136 ,35 ,12 ,5);
$pdf->Text( 137 , 39  , toSjis("達成率") );
「達成率」とすると、文字化けが起こる。
どんな風に表示されるのか、以下の図にしてしてみた。
こんな感じになる
文字化けの様子
とても読めたもんじゃなくなる。
日本語ではなく、宇宙人語だ。

  これを根本的に解決するには、PHP言語そのものの日本語処理のプログラムや、
FPDFのソースを読んだりする必要があるが、そんな実力なんぞ

  あるわけないのらー!!

  という事で、無謀(?)な事は行わない。

  考えたのは

  日本語の表現を変えれば良いのらー!!

  だった (^^;;

  そこで改善として「達成率」から「達成度」に変更した。

改善方法として (^^;;
$pdf->Rect( 136 ,35 ,12 ,5);
$pdf->Text( 137 , 39  , toSjis("達成度") );
こんな感じになる
言い回しを変更

  うーん、単純な解決法だ (^^)

  この手の文字化けは、他にも発見した。
  「年」という一文字の単語を表示させる場合にも、文字化け起こった。
  さすがに「西暦」とするには、やや不自然な感じがしたので、
この時は「年。」として、ゴマ化した (^^;;  ← そっちの方が不自然やろ!


  さて、文字化けを起こすと書いたが、誤解を招いては良くないので、
その事について、コメントします。

  実際の所、PHPのソースコードがSJISの場合だと「達成率」と表示させても
問題なく表示が可能だ。

PHPのソースがSJISだと文字化けの問題は起こらない
$pdf->Text( 137 , 39  , "達成率" );
言い回しを変更してみた
PHPソースコードをSJISにすると、上のように問題なく表示ができる。
やはり、ソースコードをEUCにして、文字列の出力の部分で
SJISに変換する際に、不具合が生じているようだ。

  だが、私のように「ソースはEUCじゃないとイヤ!」というワガママを
貫き通した時は、SJISへの変換時に不具合が生じるようだ。

  そのため、文字化け問題を起こしたくない方には

  PHPのソースはSJISにするのをお薦めします (^^)


さて、破線を引く必要がでてきたが、破線を引く関数がない。 だが、こんな時は、ちょっとした工夫があれば簡単にできる。 短い線を等間隔に引けば良いのだ!
破線を引く方法
$x = 40 ;

while ( $x < 60 )
      {
      $pdf->Line($x, 40, $x + 0.5 , 40);
      $x = $x + 1 ;
      }
こんな感じになる(拡大図)
破線
線を引く時の線の太さは初期設定では0.2mmなので、
初期設定の太さを使うと、綺麗な破線になる。

線の太さを指定する関数は、SetLineWidth( 線の太さ ) です。

  さて、FPDFを使ったプログラムの問題点。それは・・・

  プログラム間違いのエラーが表示されへん・・・

  そう、通常、PHPのプログラムの場合、構文エラーなどがあれば、
エラー表示してくれる。それも丁寧に、エラーの場所まで教えてくれる。
  しかし、FPDFを使ったプログラムの場合、何も表示されないのだ。

  「PDFファイルが生成されないからエラーが出た」という判断しかできない。

  人間なので間違いを起こす。
  コマンドの綴りの入力誤りとか、コマンドの後ろに、セミコロンの未入力など、
簡単な間違いだが、意外と見つけにくいため、修正に手間だった (^^;;

  あくまでも事実を書いているだけで、FPDFに対する批判の意図は
全くありませんので (^^;;


  なにはともあれ、実績関係のサンプル帳票が完成した。
  ボタン一つで自動生成できるため、非常に便利だ。

稟議が通り、いざ導入へ  さて、肝心のAS400(iSeries,i5)とLinuxとの連動に必要な SQL開発キットを購入する必要がある。でも大丈夫。 試作品の帳票を参考資料として、SQL開発キットの購入で稟議を挙げたら すぐに稟議が通った (^^)V 早速、PDF帳票の作成に取り掛かった。 必要なのは次の2つだった。  試し印刷に使う裏紙  枠組などを測る定規 上司が作成しているエクセルの帳票を印刷しては、定規でレイアウトなどの 寸法を測り、プログラムに反映させていく。 文字に色をつける帳票もあった。 SetTextColor()関数を使えば大丈夫だ。
青色の文字にするためには
$pdf->SetTextColor(0,60,240);
上の設定は、実は、適当に数値を入れてみた結果、
青になっただけで、キチンと設定したわけではないのだ (^^;;
他にも数値を触れば、赤になったりする。

引数の1番目は、赤色のレベル。
2番目は、グレー色のレベル。
3番目は、青色のレベル。

それぞれ0〜255まで設定できる。

  あとは、そんなに難しくない。

  円グラフを描くなどの難題があれば、七転八倒するかもしれないが、
幸いにも文字の大きさと、枠組と線を引く程度なので、難しくはない。

  ただ、定規を持って微調整したりするのが手間だった。

  なんとか上司が抱えていたエクセル帳票を、自動化する事ができた。

運用開始 12月の初め、実績データがAS400上に作られる。 いつもなら上司が「目が疲れる」と言いながら、エクセルで加工していたが、 その仕事がなくなり、別の仕事をしていた。 私がボタン1つでPDF帳票を自動生成して役員に送った。 だが、困った事もある。 帳票作成の仕事が私に振られてくるだろう。 「ボタン1つで生成できる」という事なので、プログラム作成自体も 簡単にできると思われては、ちょっと厄介だ。 しばらくは、裏紙と定規を持って、帳票作成の日々が続きそうだ (^^;;
知っておけば楽だった話 さて、枠の中に文字を入れる場合がある。 右寄せ、左寄せ、真中寄せができるのだが、12月に入って FPDFのマニュアルを見て気づいた。 それまでは、枠と文字を別々の関数で指定していた。
こんな感じで文字と枠を指定していた
$pdf->Rect(44,46,13,6);
$pdf->Text( 46 , 51  , "目標" );
1行目は座標(44,46)を起点にして横が13、縦が6の長さの枠を描く。
2行目は、座標(46,51)に「目標」という文字列を表示させる。

この場合、最初に枠を描いて、その後、枠の中に文字を入れる。
だが、別々に指定しているため、上手に真中寄せや、右寄せなどが難しい。
文字数が変われば、目算で微調整が必要になる。

  こんな事で、PDF帳票の作成をしていた時、結構、時間を無駄にしたが
実は、MultiCell()関数を使えば、簡単にできる。

  以下のようにすれば良いのだ。

こんな感じで文字と枠を指定していた
$pdf->SetXY(44,46);
$pdf->MultiCell(13,6,"目標",1,'C');
1行目は、座標を(44,46)にもっていく。
2行目は、横13、縦6の枠組を指定、枠の中には「目標」を入れる。
4番目の引数の「1」は、枠を描く意味で、これを「0」にすると
文字列を囲む枠が表示されなくなる。
最後の「'C'」は、文字列の真中寄せという意味だ。
「'R'」だと右寄せ、「'L'」だと左寄せになる。

これを使えば、簡単で綺麗に表示できる。

  こんな便利な物を、最初から知っていれば、もっと楽できたのにと思った。

  これが便利なのは、数字の表を作成する場合なのだ。
  特に、桁数が違う場合に威力を発揮する。

  数字の表だが、最初は、私は枠と数値の出力を別々にしていた。

  数字の桁が違う場合、普通にText()関数で出力すると、
文字列の先頭の座標が指定されるため、桁が違う数字が並ぶと
綺麗に揃わない。

こんな感じになる
$value = 424963 ;
$pdf->Rect( 171 , 40 ,23 , 8);
$pdf->Text( 46 , 51  , number_format($value) );

$value = 1788146 ;
$pdf->Rect( 171 , 48 ,23 , 8);
$pdf->Text( 46 , 51  , number_format($value) );
ズレの度合い
Text()関数で、文字列を出力させる場合、
先頭の文字の位置を指定するため、数字の場合、
1番上の桁の位置が揃った形になる。
とても数字の表を作るのには、綺麗な見栄えにはならない。

ちなみに、number_format()関数は、数値を3桁ごとに「,」を入れた
文字列に変換する関数だ。金額表示の時には便利だ。

  そこで、苦し紛れに以下の関数を作った。

数字の並びのズレを調整するための
苦し紛れで作成した独自関数
function yokozure($value)
{
  if ( $value < 0 )
     {
     $value *= -10 ;     
     }

  if ( $value < 0 ) return 0 ;
  if ( $value < 10      )      return 8  ;
  if ( $value < 100     )      return 7  ;
  if ( $value < 1000    )      return 6  ;
  if ( $value < 10000   )      return 5  ;
  if ( $value < 100000  )      return 4  ;
  if ( $value < 1000000 )      return 3  ;
  if ( $value < 10000000  )    return 2  ;
  if ( $value < 100000000 )    return 1  ;


  return 0 ;
}
この関数の場合、表示させたい数値を代入すると、桁数分、
横にズラす値が出てくる物だ。
マイナスの場合、数値の前に「-」の符号がつくため、
一文字、多くずらす仕掛けにした。

  上の苦し紛れで作った独自関数を使って、以下のようにしていた。

数値の表を、こんな形で作っていた
$value = 424963 ;
$yoko = yokozure($value);
$pdf->Rect( 171 , 40 ,23 , 8);
$pdf->Text( 46 + $yoko , 51  , number_format($value) );

$value = 1788146 ;
$yoko = yokozure($value);
$pdf->Rect( 171 , 48 ,23 , 8);
$pdf->Text( 46 + $yoko , 51  , number_format($value) );
赤い部分は、桁数の違いによる表示のズレを調整している部分。
数値の1番上の桁が出力される位置をズラす事で、
後ろの桁の場所を揃えようと考えた。

  だが、私が作った関数は、あまりにもお粗末な関数なので、
微妙なズレなどが直らない。以下のようになってしまう。

こんなダサい状態になるのだ
ズレが微妙に出ている
こんな感じで、微妙なズレが残ってしまう。
ダサい感じがしてしまう。

しかも、数値の文字フォントを買えれば、ズレる割合も変わるので、
私が苦し紛れに作った関数なんぞ、汎用性は全くない。

  だが、MultiCell()関数を使えば、あっさりと解決できる。
  というわけで、以下のようにしてみました。

数値の表を、こんな形で作ってみたら
$value = 424963 ;
$pdf->SetXY(171,40);
$pdf->MultiCell(23,8, number_format($value) ,1,'R');

$value = 1788146 ;
$pdf->SetXY(171,48);
$pdf->MultiCell(23,8, number_format($value) ,1,'R');
出力結果は
MultiCell()関数で解決した様子
綺麗に右寄せになった。
これだとダサくない表が作成できる。


便利な機能(ページ数の掲載) 今回の帳票作成では、ページ数の表示は行わなかったが、 枚数の多い帳票になると、ページ数を割り当てないと 順番がわからなくなったりする。 なので、ページ数が表示できれば便利だ。 PageNo()関数を使えば良い。 返り値として、現在のページ数が出てくるからだ。 使い方は以下のようにします。
ページ数の出力方法
$page = $pdf->PageNo();
$pdf->Text(290,205,$page);
PageNo()関数で、ページ数をだした後は、
Text()関数を使って表示させるだけだ。

上のように、紙の一番右下に表示させるようにしたら
以下の図のようになる。
ページ数の表示


便利な機能(画像の掲載) 今回の帳票作成で、画像の張り付けは触れませんでしたが、 jpg、gif、png型式の画像を張り付ける事も可能です。 会社のロゴを付けれたり、ハンコを画像データにして張り付けると、 見積書や請求書などにも使えます。 画像の張り付けができるのは便利だ。 ところで「できる」と書きながら、証拠を見せないのは良くないので 簡単なプログラムを載せてみました。
画像を載せたPDF出力のプログラム
<?php

mb_internal_encoding('SJIS');

require('japanese.php');

$pdf=new PDF_Japanese();
$pdf->FPDF(Portrait ,mm,A4);
$pdf->AddSJISFont();
$pdf->Open();
$pdf->AddPage();
$pdf->SetFont('SJIS','',18);

$pdf->Text( 60,30,"ツマガリのケーキは美味しい!");

$pdf->Image('tumagari.jpg' ,80 , 50);

$pdf->Output();
?>
出力結果は
ツマガリのケーキ

  美味しそうなケーキの写真が張り付けられるのだ。
  甘党の私は、すぐにでもツマガリへ行ってケーキを買いたくなるのだが
ケーキばかり食べると・・・

  自慢の三段腹が大きくなった結果

  今、履いているズボンが入らなくなるのだ!!

  今、履いているズボンが入らなくなると、買い替える必要に迫られ
不経済なのだ。そして、生活習慣病も他人事ではなくなる (^^;;

  という事で、ケーキを食べたい衝動を抑える今日この頃。

<
ツマガリのケーキは最高だ!
「ツマガリ」とは兵庫県西宮市の甲陽園にあるケーキ屋で
知る人ぞ知る名店なのだ。そして、手頃な値段で買える。
阪急甲陽園駅から歩いてすぐの場所にある。

http://www.tsumagari.co.jp/

私はツマガリへ行く時は、甲陽園駅ではなく、阪急夙川駅から
阪急甲陽線に沿って散策する。環境が良い場所なので散策にはお薦め。
桜の時期は、全国桜百選に挙げられている夙川公園の桜を見ながら
甲陽園へ歩かれるもお薦め。

この辺りは野坂昭如氏の原作でジブリの映画にもなった
「火垂るの墓」の舞台になっている場所だ。

そして、最近、放映されたアニメ「涼宮ハルヒ」の
舞台になっている場所にも近く、甲陽園周辺の高校生は
ハルヒが通う北高(県立西宮北高校)へ通っている。
大リーガーの田口選手も、西宮北高校の出身です。

ちなみに、私も西宮北高校の出身なので、ハルヒを見る度に
「おっ、懐かしい」という感じで見ています。

是非、美味しいケーキを求めて関西に来られた方には
ツマガリのケーキと周辺の散策を、お薦めします (^^)


まとめ fpdf.phpと日本語パッチを使えば、簡単にPDFファイルが出力できる Webアプリが組める事がわかりました。 他にも機能を付け加えたい場合は、オープンソースの利点として ソースを解読して、ソースを改造すれば良いのですが、 さすがに、FPDFのプログラムを読む気が起こらないので、 今回は、使う人に徹しました。 注意点は、日本語処理の際に、日本語パッチを「FPDF_japanese」を使う場合、 私のように「PHPのソースはEUCじゃなとイヤ」と、ワガママを言わない事です。 これさえなければ、文字化けの心配はありません。 基幹システムと連動させれば、高いベンダー製品を買わなくても 無料でPDF帳票の作成ができるため、中小企業にはお薦めです!! あと、エクセルで出力させたい場合は、PHPのPEARを使えば 良いみたいですが、まだ、触った事がないので、何とも言えませんが、 余裕があれば、やってみたいです。

次章:「iSeriesAccessを活用したODBC経由のAS400(iSeries,i5)とLinuxの連動に成功」を読む
前章:「hdparmコマンドの使い方」を読む
目次:システム奮闘記に戻る

Tweet