FPDF+FPDIでUTF-8でちゃんと日本語使えるようにする

いろいろ面倒

PHPからPDFファイルが生成できる有名ライブラリであるFPDFは、どうもすでに古いライブラリのようです。昨今ではPDFを生成するPHPを開発するんなら別の新し目のライブラリを利用した方がいいという空気になっているっぽく、ほとんどの参考サイトが古い情報のままでした。そのためか、FPDF最新版で色々準備しようとしたところすんなりいきませんでした。。
ということで、今回、現在(2014.3)最新版のFPDF1.7でも、表題の目的が果たせるように試行錯誤しましたので、ご参考にしていただければと思います。

FPDF本体をダウンロード

2014.3現時点では1.7が最新バージョンです。まずはこれをダウンロードします。

ダウンロードしたら解凍してください。ここではfpdfというディレクトリにします。これに全て詰め込んでいきます。 ただし、マニュアルやチュートリアルは公式サイトでも確認できるので、余計なディレクトリやファイルは削除します。必要な方は残しててもいいですが。


fpdf/font/
fpdf/makefont/
fpdf/fpdf.php

ちなみに、この今ダウンロードしたFPDFのライブラリだけだと、なんと日本語が扱えないという致命的な問題があり、別途プログラムが必要となります。

FPDF日本語対応、japanese.php!

FPDFの日本語対応のため、以下サイトからjapanese.zipをダウンロードし、解凍して出来たjapanese.phpfpdfに入れてください。

このサポートサイトにはmbfpdf10b.zipというマルチバイト対応の別アプローチも用意されていますが、今回は使いません。というかデッドリンクでダウンロード出来ないですね・・。(2014.3.14現在)


fpdf/font/
fpdf/makefont/
fpdf/fpdf.php
fpdf/japanese.php

テンプレートを読み込むためのFPDI

次に、既存のPDFファイルをテンプレート的に読み込むことができるFPDIというライブラリがあります。名前がややこしいですので間違えないように。 以下サイトからFPDF_TPLFPDIと書いてある箇所からそれぞれダウンロード・解凍し、同様にfpdfディレクトリに入れてください。


fpdf/font/
fpdf/makefont/
fpdf/fpdf.php
fpdf/japanese.php
fpdf/fpdf_tpl.php
fpdf/filters/
fpdf/fpdi.php
fpdf/fpdi_pdf_parser.php
fpdf/fpdi2tcpdf_bridge.php
fpdf/pdf_context.php
fpdf/pdf_parser.php

ライブラリの修正

さて、ファイルは揃ったのですが、このままでは使えません。ちゃんと動くようにライブラリ自体に手を入れる必要があります。

1. japanese.php の修正

以下のように修正と追加をしてください。

<?php
require('fpdi.php'); // fpdf.php -> fpdi.php

$SJIS_widths = array(' '=>278,'!'=>299,'"'=>353,'#'=>614,'$'=>614,'%'=>721,'&'=>735,'\''=>216,
    '('=>323,')'=>323,'*'=>449,'+'=>529,','=>219,'-'=>306,'.'=>219,'/'=>453,'0'=>614,'1'=>614,
   'x'=>503,'y'=>529,'z'=>453,'{'=>326,'|'=>380,'}'=>326,'~'=>387);

class PDF_Japanese extends FPDI // FPDF -> FPDI
{
function AddCIDFont($family, $style, $name, $cw, $CMap, $registry)
}

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

2. fpdf_tpl.php の修正

どうもTCPDFというものが邪魔をして、FPDFクラスが読み込まれないという自体が起きているらしくエラーになるため、回避策として、fpdf_tpl.phpの冒頭に以下のように1行を追加します。

<?php
require('fpdf.php');
//
//  FPDF_TPL - Version 1.2.3
//
//    Copyright 2004-2013 Setasign - Jan Slabon

3. PHPのNoticeエラーを非表示にする

PDFを生成する際にライブラリからNoticeエラーが出る場合があるので、PDFをブラウザに直接出力する場合などに支障がある場合は、該当のPHPファイルのPDF生成を呼ぶ前に以下の行を追加してNoticeエラーを非表示にしておくといいです。

error_reporting(E_ALL & ~E_NOTICE);

エラーメッセージの抑制はphp.ini.htaccessで設定してもいいのですが、私的には他の必要な箇所ではNoticeが出て欲しかったりするので、部分的に書いています。

準備完了!

ライブラリの方はこれで準備完了です!
あとは実際にPDFを生成するプログラムを書いていけばいいです。但し、一つ注意があります。
実はこの今用意したライブラリ群は、内部では文字コードをUTF-16で処理を行うため、各種関数に渡す文字列をUTF-8→UTF-16の変換を施してから渡す必要があります。

サンプルプログラム

以下サンプルPHPは、文字コードUTF-8で記述して下さい。 また、同パスに適当なtemplate.pdfを配置してお試し下さい。


fpdf/(上記で用意したセット)
sample.php
template.pdf
<?php
// Noticeエラー非表示
error_reporting(E_ALL & ~E_NOTICE);

// PDFインスタンス作成
include_once('fpdf/japanese.php');
$pdf = new PDF_Japanese('P', 'mm', 'A4');
$pdf->AddPage(); //ページを追加

// UTF-16フォントロード
$pdf->AddUniJISFont('MS-Mincho','UniJIS_Mincho');
$pdf->AddUniJISFont('MS-Gothic','UniJIS_Gothic');
 
//テンプレートPDF読み込み
$pageno = $pdf->setSourceFile('template.pdf');
$tplidx = $pdf->ImportPage(1);
$pdf->useTemplate($tplidx);
 
// 文字書き込み:明朝体
$pdf->SetFont('UniJIS_Mincho', '', 20);
$pdf->SetTextColor(255,0,0);
$str = mb_convert_encoding('あいうえお 一期一会 明朝体',"unicode","utf-8"); // UTF8 -> UTF16変換
$pdf->Text(5, 10, $str);

// 文字書き込み:ゴシック体
$pdf->SetFont('UniJIS_Gothic', '', 20);
$pdf->SetTextColor(0,0,255);
$str = mb_convert_encoding('あいうえお 一期一会 ゴシック体',"unicode","utf-8"); // UTF8 -> UTF16変換
$pdf->Text(5, 20, $str);
 
// PDF出力
// $pdf->Output('sample.pdf', "F"); // ファイルに出力する場合
$pdf->Output('sample.pdf', "I"); // 画面に出力する場合
 
// PDFクローズ
$pdf->Close();
 
exit;

以上です。 ご参考になれば幸いです。

ちなみに、FPDFのCell()MultiCell()を使うと多々文字化けするようですので、改行処理を自力で書いてText()を使うのが良さそうです。

確認したバージョン

  • FPDF 1.7
  • japanese.php (Date: 08-17-03 17:43 投稿版)

参考にさせていただいたサイト