【PDF処理 -- PHP】 FPDF v1.6 + FPDI 日本語利用詳細

  ライブラリビルド手順



FPDF と FPDI を使用して、両方の機能を日本語で利用できるようにする為の
環境作成手順を以下に示します ( EUC と Unicode の対応方法はこちら )

C:\user\php\pdf_action というディレクトリを作成し、AN HTTPD で C:\user\php を
/php でエイリアスしています。

1) FPDF の ダウンロードおよび解凍


   FPDF 1.6(fpdf16.zip) をダウンロードして C:\user\php\pdf_action 
   内にダウンロードして解凍します。

   必要無いディレクトリとファイルを削除して以下のようにして下さい
   ( C:\user\php\pdf_action\fpdf16 内 )




2) japaneze.php のダウンロード と配置


   FPDF のサイトにある japaneze.php をダウンロードして、
   C:\user\php\pdf_action\fpdf16 に置きます。




3) FPDI のダウンロード・解凍・配置


   FPDI-1.2.zip をダウンロードして解凍し、内容を全て C:\user\php\pdf_action\fpdf16
   に移動します。
  ( 2009/07/09 現在 FPDI-1.3.zip です )




4) fpdf_tpl.php のダウンロード・解凍・配置


   FPDF_TPL-1.1.1.zip をダウンロードして解凍し、C:\user\php\pdf_action\fpdf16
   に置きます。
  ( 2009/07/09 現在 FPDF_TPL-1.1.3.zip です )

FPDI
FPDF
FPDF_TPL-1.1.1





5) japanese.php を変更

  ( 2009/07/09 現在 japanese.php に加えて fpdf_tpl.php も変更 )


   まず先頭で、fpdi.php を参照するようにします
   ( オリジナルは fpdf.php を参照しています )
   さらに、クラスで fpdi を継承するように変更して下さい

  
<?php
require('fpdi.php');
  

  
class PDF_Japanese extends fpdi
{
  

( 2009/07/09 現在、fpdf_tpl.php の変更 )
どうも、FPDI が FPDF から TCPDF に乗り換えるコードを書いたせいで、
FPDF の参照がうまくいかずにエラーになるようです
  
<?php
require('fpdf.php');
  

6) 日本語フォントを使用する為の変更


   japanese.php は、そのままではWindows 環境が考慮されていませんので
   以下のように変更します( デフォルトは MS 明朝になります )

   ※ 引数部分と $name=$font; に必ず変更します

  
function AddSJISFont($font='MS-Mincho',$family='SJIS')
{
	//Add SJIS font with proportional Latin
	$name=$font;
	$cw=$GLOBALS['SJIS_widths'];
	$CMap='90msp-RKSJ-H';
	$registry=array('ordering'=>'Japan1','supplement'=>2);
	$this->AddCIDFonts($family,$name,$cw,$CMap,$registry);
}
  



  フォントのポストスクリプト名の確認



フォントは、PC にインストールされているフォントを使用するのですが、日本語名を指定できません。
ですから、ポストスクリプト名が必要になるのですが、簡単な確認方法がありません。

GIMP がインストールされておれば、そこから知る事もできますが、
Java の 6 がインストールされている PC であれば、以下から確認できると思います

PC フォントの一覧表示アプレット



  半角文字幅の調整

japanese.php の先頭にあるデータは、半角文字を表示する時の幅を指定しています。
しかし、デフォルトでは微妙に幅の違いにより文字同士が接近しすぎます。
使用者の環境に合わせて変更すると良いでしょう( 漢字はたぶん計算しているんだと思います )

↓変更後のサンプル
  
$SJIS_widths=array(' '=>278,'!'=>299,'"'=>353,'#'=>614,'$'=>614,'%'=>721,'&'=>735,'\''=>216,
	'('=>323,')'=>323,'*'=>449,'+'=>529,','=>219,'-'=>306,'.'=>219,'/'=>453,'0'=>614,'1'=>614,
	'2'=>614,'3'=>614,'4'=>614,'5'=>614,'6'=>614,'7'=>614,'8'=>614,'9'=>614,':'=>219,';'=>219,
	'<'=>529,'='=>529,'>'=>529,'?'=>486,'@'=>744,'A'=>646,'B'=>604,'C'=>617,'D'=>681,'E'=>567,
	'F'=>537,'G'=>647,'H'=>738,'I'=>320,'J'=>433,'K'=>637,'L'=>520,'M'=>904,'N'=>710,'O'=>716,
	'P'=>605,'Q'=>520,'R'=>623,'S'=>520,'T'=>601,'U'=>690,'V'=>668,'W'=>990,'X'=>681,'Y'=>634,
	'Z'=>578,'['=>316,'\\'=>614,']'=>316,'^'=>529,'_'=>500,'`'=>387,'a'=>509,'b'=>566,'c'=>478,
	'd'=>565,'e'=>503,'f'=>337,'g'=>549,'h'=>580,'i'=>540,'j'=>266,'k'=>544,'l'=>540,'m'=>854,
	'n'=>579,'o'=>550,'p'=>578,'q'=>566,'r'=>410,'s'=>444,'t'=>540,'u'=>575,'v'=>512,'w'=>760,
	'x'=>503,'y'=>529,'z'=>453,'{'=>326,'|'=>380,'}'=>326,'~'=>387);
  
SQL と lightbox が綺麗に表示されるように変更しています。




  印字サンプル

実際の印字サンプルの実行

実際は、データベースからデータを取り込んで業務処理別に印字しますので、
その際のメンテナンス性を考えて、 control.php と model.php という構成です。

model.php は、japanese.php で定義されている PDF_japanese を継承して
クラス内で印字処理をパッケージしています。

まだ、標準化の入り口程度しか実装されていませんが、
印字処理は座標処理がとても有効で、あとあと潰しがききます。
で、それと関連して最も大事なのが、「基点」を作成するという事です。

これによって、全体の印字位置を容易に移動する事がてきます。

通常フォントの種類を変える事は無いので、メソッドはその対応をしていませんが、
ここではサンプルとして、2種類のフォントを使って印字しています。



model.php
  
<?php
require('japanese.php');

class PDF_lightbox extends PDF_japanese
{
	public $bx = 0;
	public $by = 0;

# **********************************************************
# 新規ページ
# **********************************************************
function newUserPage($Title,$Option="") {

	// 新しいページを追加
	// P : ポートレイト( 縦 )
	// 背景色 セット
	$this->AddPage('P');
	$this->SetFillColor( 255, 255, 255 );

	// 号
	$this->SetFont( 'SJIS', '', 12 );
	$this->LocText( 150, -20, '第             号' );

	// タイトル印字
	$this->SetFont( 'SJIS', 'B', 20 );
	$this->LocText( 65, 0, $Title );

	// 個人情報
	$x = 40;
	$y = 23;

	// 氏名
	$this->SetFont( 'SJIS', '', 16 );
	$this->LocText( 40, 23, "山田 太郎" );

	$x = 40;
	$y = 60;

	$this->SetFont( 'SJIS-2', 'B', 18 );
	$Text = '上記の者は、間違い無く';
	$this->LocText( $x, $y, $Text );

	$this->SetFont( 'SJIS-2', 'I', 18 );
	$Text = '銀プログラマである事を';
	$this->LocText( $x, $y+20, $Text );

	$this->SetFont( 'SJIS-2', 'B', 18 );
	$Text = '証明致します。';
	$this->LocText( $x, $y+40, $Text );


	$dt = explode( "/", date("m/d/Y") );
	
	// 平成
	$this->SetFont( 'SJIS', 'B', 13 );
	$dt[2] = ($dt[2]+0) - 1988;
	$this->LocText( $x+7, $y+60, "平成" );

	$this->LocText( $x+20, $y+60, sprintf( "%d年", $dt[2]+0 ), 'I', 12 );
	$this->LocText( $x+37, $y+60, sprintf( "%d月", $dt[0]+0 ) );
	$this->LocText( $x+50, $y+60, sprintf( "%d日", $dt[1]+0 ) );

	$this->SetFont( 'SJIS', 'B', 13 );
	$this->LocText( $x+40, $y+95, "架空法人 システム家成育社" );
	$this->LocText( $x+40, $y+105, "SQLの窓学院" );
	$this->LocText( $x+68, $y+115, "校 長" );

	$this->LocText( $x+94, $y+115, "lightbox" );

}

# **********************************************************
# 座標設定印字
# **********************************************************
function LocText( $x, $y, $str, $style='NONE', $size=14 ) {

	if ( $style != 'NONE' ) {
		$this->SetFont('SJIS',$style,$size);
	}
	$this->Text( $this->bx + $x, $this->by + $y, $str );

}

# **********************************************************
# 印字基点座標設定
# **********************************************************
function SetBase( $x=0, $y=0 ) {

	$this->bx = $x;
	$this->by = $y;

}

}
?>
  

control.php
  
<?
# **********************************************************
# ライブラリ類の参照
# **********************************************************
$sep = PATH_SEPARATOR;
set_include_path( ".{$sep}fpdf16" );

# **********************************************************
# SJIS への変換環境( このファイルは SHIFT_JIS )
# **********************************************************
mb_language( "ja" );
mb_internal_encoding("UTF-8");

# **********************************************************
# PDF を使用する為のユーザ環境
# **********************************************************
require_once( "model.php");

# **********************************************************
# PDF アクセス用のインスタンス作成
# ( PDF_lightbox は、model.php 定義 )
# **********************************************************
$pdf = new PDF_lightbox();
// 基点の定義
$pdf->SetBase( 0, 60 );

# **********************************************************
# 日本語環境
# ( デフォルトの MS-Mincho )
# **********************************************************
$pdf->AddSJISFont( );
$pdf->AddSJISFont("MS-Gothic", "SJIS-2");

# **********************************************************
# 印刷処理
# **********************************************************
$pdf->newUserPage( '銀 色 の 証 明 書' );

# **********************************************************
# PDF を ブラウザに出力
# **********************************************************
$pdf->Output();

?>
  



  固定部分をフォームとして出力し、FPDI の機能を使って非固定部分のみ出力する

いわゆる、「フォームオーバレイ」というやつですが、印刷用紙を変えて内容を印刷するようなものです。

まず、元のコードの非固定部分をコメントにし、最後の出力を ファイルに変更して form.pdf を作成します

  
$pdf->Output( "form.pdf", "F" );
  
作成された PDF

作成された PDF を読み込んで印刷するサンプルコードが以下です

( オーバレイは AddPage 後に実行する必要があります )
実行

  
<?php
require('japanese.php');

class PDF_lightbox extends PDF_japanese
{
	public $bx = 0;
	public $by = 0;

# **********************************************************
# 新規ページ
# **********************************************************
function newUserPage($Title,$Option="") {

	// **********************************************************
	// PDF を読み込んでページ数を得る
	// **********************************************************
	$pagecount = $this->setSourceFile("form.pdf");
	// ページ番号より ID を取得する
	$tplidx = $this->ImportPage($pagecount);

	// 新しいページを追加
	// P : ポートレイト( 縦 )
	// 背景色 セット
	$this->AddPage('P');

	// フォームオーバレイとして適用する
	$this->useTemplate($tplidx);

	$this->SetFillColor( 255, 255, 255 );

	// 個人情報
	$x = 40;
	$y = 23;

	// 氏名
	$this->SetFont( 'SJIS', '', 16 );
	$this->LocText( 40, 23, "山田 太郎" );

	$x = 40;
	$y = 60;

	$dt = explode( "/", date("m/d/Y") );

	$this->LocText( $x+20, $y+60, sprintf( "%d年", $dt[2]+0 ), 'I', 12 );
	$this->LocText( $x+37, $y+60, sprintf( "%d月", $dt[0]+0 ) );
	$this->LocText( $x+50, $y+60, sprintf( "%d日", $dt[1]+0 ) );

}

# **********************************************************
# 座標設定印字
# **********************************************************
function LocText( $x, $y, $str, $style='NONE', $size=14 ) {

	if ( $style != 'NONE' ) {
		$this->SetFont('SJIS',$style,$size);
	}
	$this->Text( $this->bx + $x, $this->by + $y, $str );

}

# **********************************************************
# 印字基点座標設定
# **********************************************************
function SetBase( $x=0, $y=0 ) {

	$this->bx = $x;
	$this->by = $y;

}

}
?>
  



  英文フォントを使用したい場合

PC にインストールされている全てのフォントが使用できるわけではありません。
( 日本語だったらフリーフォントをインストールして、ポストスクリプト名指定するだけなんですが )

たぶん、それぞれのフォントの幅データにそれぞれのこだわりがあるんでしょうか。
そういう仕様になっていて、fpdf16\font ディレクトリに、該当するフォント用のファイルが無いとエラーになります。
どうやら、fpdf16/font/makefont/makefont.php を使って作るみたいですが、よく解りません。
( 幅データはけっこういいかげんみたいですが・・・、日本語環境のせいなんでしょうか )



今調査終了でなんとかなりました。
普通じゃちょっと無理なんで、慣れた人だけが解る程度で書きます

まず、以下のサイト( 英語ですらないですが ) ここから、ttf2pt1.exe が必要である事が解ります

http://laterminal.wordpress.com/2008/04/03/anexar-fuentes-extra-para-un-pdf-clase-fpdf/

で、ダウンロードが以下
http://ttf2pt1.sourceforge.net/

ソースを解凍して、Visual studio 2005 でビルドしました。
以下がそのバッチファイル

  
Set AddPath=C:\Program Files\Microsoft Visual Studio 8\Common7\IDE
Set PATH=%AddPath%;%PATH%
Set CL8="C:\Program Files\Microsoft Visual Studio 8\VC\bin\cl.exe"
Set LINK8="C:\Program Files\Microsoft Visual Studio 8\VC\bin\link.exe"
Set INC81="C:\Program Files\Microsoft Visual Studio 8\VC\include"
Set INC82="C:\Program Files\Microsoft Platform SDK\Include"
Set INC83="C:\Program Files\Microsoft Platform SDK\Include\atl"
Set LIB81="C:\Program Files\Microsoft Visual Studio 8\VC\lib"
Set LIB82="C:\Program Files\Microsoft Platform SDK\Lib"
Set LIBS1=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib
Set LIBS2=shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib LIBCMT.lib

%CL8% -DWINDOWS -c bdf.c /I%INC81% /I%INC82% /I%INC83%
%CL8% -DWINDOWS -c ttf2pt1.c /I%INC81% /I%INC82% /I%INC83%
%CL8% -DWINDOWS -c pt1.c /I%INC81% /I%INC82% /I%INC83%
%CL8% -DWINDOWS -c ttf.c /I%INC81% /I%INC82% /I%INC83%
%CL8% -DWINDOWS -c t1asm.c /I%INC81% /I%INC82% /I%INC83%
%CL8% -DWINDOWS -c bitmap.c /I%INC81% /I%INC82% /I%INC83%

%LINK8% /LIBPATH:%LIB81% /LIBPATH:%LIB82% ttf2pt1.obj pt1.obj t1asm.obj ttf.obj bdf.obj bitmap.obj  %LIBS1% %LIBS2%
  

出来上がったのを使って以下を実行

  
ttf2pt1 -a C:\WINNT\Fonts\impact.ttf impact
  

この結果で出来上がった、impact.afm を、fpdf16\font\makefont に置いて、以下の PHP を作成して実行

  
<?

require('makefont.php');

MakeFont('C:\\WINNT\\Fonts\\impact.ttf','impact.afm','cp1252');

?>
OK
  

出来上がった impact.php と impact.z を fpdf16\font に置く。

後は、 AddFont("Impact") しておいて、SetFont("Impact") とする。
以下が実行結果の画像








  FPDF v1.6 の内容

v1.6 (2008-08-03)
- GIF image support.
- Images can now trigger page breaks.
- Possibility to have different page formats in a single document.
- Document properties (author, creator, keywords, subject and title) can now be specified in UTF-8.
- Fixed a bug: when a PNG was inserted through a URL, an error sometimes occurred.
- An automatic page break in Header() doesn't cause an infinite loop any more.
- Removed some warning messages appearing with recent PHP versions.
- Added HTTP headers to reduce problems with IE.













   SQLの窓    create:2008/08/25  update:2015/09/23   管理者用(要ログイン)





フリーフォントツール

SQLの窓ツール

SQLの窓フリーソフト

写真素材

一般ツールリンク

SQLの窓

フリーソフト

JSライブラリ