PHPを使用してPDF中国語ドキュメントを作成する方法
FPDF (www.fpdf.org) を使用しています。 fpdf クラス ライブラリをダウンロードした後、中国語をサポートするには次の中国語クラス ライブラリを使用する必要がありますが、使用できる中国語フォントは 1 つだけです (中国語の模倣宋王朝)。私はこれについて長い間心配していましたが、今、次の方法を使用して TrueType フォントを pt1 フォントに変換することができました。
以下は、FPDF にある中国語クラス ライブラリです:
require('fpdf.php');
$Big5_widths=array(' '=>250,'!'=>250,'"'=>408,'#'=>668,'$'=>490,'%'=> 875,'&'=>698,'''=>250,
'('=>240,')'=>240、'*'=>417、'+'=>667、','=>250、'-'=>313、'。 '=>250、'/'=>520、'0'=>500、'1'=>500、
'2'=>500、'3'=>500、'4'=>500、'5'=>500、'6'=>500、'7'=>500、'8 '=>500,'9'=>500,':'=>250,';'=>250,
'<'=>667、'='=>667、'>'=>667、'?'=>396、'@'=>921、'A'=>677、 'B'=>615、'C'=>719、'D'=>760、'E'=>625、
'F'=>552、'G'=>771、'H'=>802、'I'=>354、'J'=>354、'K'=>781、'L '=>604、'M'=>927、'N'=>750、'O'=>823、
'P'=>563、'Q'=>823、'R'=>729、'S'=>542、'T'=>698、'U'=>771、'V '=>729、'W'=>948、'X'=>771、'Y'=>677、
'Z'=>635、'['=>344、''=>520、']'=>344、'^'=>469、'_'=>500、'''' =>250、'a'=>469、'b'=>521、'c'=>427、
'd'=>521、'e'=>438、'f'=>271、'g'=>469、'h'=>531、'i'=>250、'j '=>250、'k'=>458、'l'=>240、'm'=>802、
'n'=>531、'o'=>500、'p'=>521、'q'=>521、'r'=>365、's'=>333、't '=>292、'u'=>521、'v'=>458、'w'=>677、
'x'=>479、'y'=>458、'z'=>427、'{'=>480、'|'=>496、'}'=>480、'~ '=>667);
$GB_widths=array(' '=>207,'!'=>270,'"'=>342,'#'=>467,'$'=>462,'%'=> 797,'&'=>710,'''=>239,
'('=>374,')'=>374、'*'=>423、'+'=>605、','=>238、'-'=>375、'。 '=>238、'/'=>334、'0'=>462、'1'=>462、
'2'=>462、'3'=>462、'4'=>462、'5'=>462、'6'=>462、'7'=>462、'8 '=>462,'9'=>462,':'=>238,';'=>238,
'<'=>605、'='=>605、'>'=>605、'?'=>344、'@'=>748、'A'=>684、 'B'=>560、'C'=>695、'D'=>739、'E'=>563、
'F'=>511、'G'=>729、'H'=>793、'I'=>318、'J'=>312、'K'=>666、'L '=>526、'M'=>896、'N'=>758、'O'=>772、
'P'=>544、'Q'=>772、'R'=>628、'S'=>465、'T'=>607、'U'=>753、'V '=>711、'W'=>972、'X'=>647、'Y'=>620、
'Z'=>607、'['=>374、''=>333、']'=>374、'^'=>606、'_'=>500、'''' =>239、'a'=>417、'b'=>503、'c'=>427、
'd'=>529、'e'=>415、'f'=>264、'g'=>444、'h'=>518、'i'=>241、'j '=>230、'k'=>495、'l'=>228、'm'=>793、
'n'=>527、'o'=>524、'p'=>524、'q'=>504、'r'=>338、's'=>336、't '=>277、'u'=>517、'v'=>450、'w'=>652、
'x'=>466、'y'=>452、'z'=>407、'{'=>370、'|'=>258、'}'=>370、'~ '=>605);
クラス PDF_ Chinese は FPDF を拡張します
{
function AddCIDFont($family,$style,$name,$cw,$CMap,$registry)
{
$i=count($this->フォント)+1;
$fontkey=strto lower($family).strtoupper($style);
$this->fonts[$fontkey]=array('i'=>$i,'type'=>'Type0','name'=>$name,'up'=>-120, 'ut'=>40,'cw'=>$cw,'CMap'=>$CMap,'registry'=>$registry);
}
関数AddBig5Font($family='Big5')
{
$cw=$GLOBALS['Big5_widths'];
$name='MSungStd-Light-Acro';
$CMap='ETenms-B5-H';
$registry=array('ordering'=>'CNS1','supplement'=>0);
$this->AddCIDFont($family,'',$name,$cw,$CMap,$registry);
$this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry);
$this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry);
$this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry);
}
関数AddGBFont($family='GB')
{
$cw=$GLOBALS['GB_widths'];
$name='STSongStd-Light-Acro';
$CMap='GBKp-EUC-H';
$registry=array('ordering'=>'GB1','supplement'=>2);
$this->AddCIDFont($family,'',$name,$cw,$CMap,$registry);
$this->AddCIDFont($family,'B',$name.',Bold',$cw,$CMap,$registry);
$this->AddCIDFont($family,'I',$name.',Italic',$cw,$CMap,$registry);
$this->AddCIDFont($family,'BI',$name.',BoldItalic',$cw,$CMap,$registry);
}
関数 GetStringWidth($s)
{
if($this->CurrentFont['type']=='Type0')
return $this->GetMBStringWidth($s);
それ以外
returnparent::GetStringWidth($s);
}
関数 GetMBStringWidth($s)
{
//GetStringWidth() のマルチバイト バージョン
$l=0;
$cw=&$this->現在のフォント['cw'];
$nb=strlen($s);
$i=0;
while($i
{
$c=$s[$i];
if(ord($c)
{
$l+=$cw[$c];
$i++;
}
それ以外
{
$l+=1000;
$i+=2;
}
}
return $l*$this->FontSize/1000;
}
関数 MultiCell($w,$h,$txt,$border=0,$align='L',$fill=0)
{
if($this->CurrentFont['type']=='Type0')
$this->MBMultiCell($w,$h,$txt,$border,$align,$fill);
それ以外
親::MultiCell($w,$h,$txt,$border,$align,$fill);
}
関数 MBMultiCell($w,$h,$txt,$border=0,$align='L',$fill=0)
{
//MultiCell() のマルチバイトバージョン
$cw=&$this->現在のフォント['cw'];
if($w==0)
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->フォントサイズ;
$s=str_replace("r",'',$txt);
$nb=strlen($s);
if($nb>0 および $s[$nb-1]=="n"
$nb--;
$b=0;
if($border)
{
if($border==1)
{
$border='LTRB';
$b='LRT';
$b2='LR';
}
それ以外
{
$b2='';
if(is_int(strpos($border,'L')))
$b2.='L';
if(is_int(strpos($border,'R')))
$b2.='R';
$b=is_int(strpos($border,'T')) ? $b2.'T' : $b2;
}
}
$sep=-1;
$i=0;
$j=0;
$l=0;
$ns=0;
$nl=1;
while($i
{
//次のキャラクターを取得します
$c=$s[$i];
// ASCII か MB かを確認します
$ascii=(ord($c)
if($c=="n"
{
//明示的な改行
if($this->ws>0)
{
$this->ws=0;
$this->_out('0 Tw');
}
$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
$i++;
$sep=-1;
$j=$i;
$l=0;
$ns=0;
$nl++;
if($border と $nl==2)
$b=$b2;
続けます;
}
if(!$ascii)
{
$sep=$i;
$ls=$l;
}
elseif($c==' ')
{
$sep=$i;
$ls=$l;
$ns++;
}
$l+=$ascii ? $cw[$c] : 1000;
if($l>$wmax)
{
//自動改行
if($sep==-1 または $i==$j)
{
if($i==$j)
$i+=$ascii ? 1 : 2;
if($this->ws>0)
{
$this->ws=0;
$this->_out('0 Tw');
}
$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
}
それ以外
{
if($align=='J')
{
if($s[$sep]==' ')
$ns--;
if($s[$i-1]==' ')
{
$ns--;
$ls-=$cw[' '];
}
$this->ws=($ns>0) ? ($wmax-$ls)/1000*$this->フォントサイズ/$ns : 0;
$this->_out(sPRintf('%.3f Tw',$this->ws*$this->k));
}
$this->Cell($w,$h,substr($s,$j,$sep-$j),$b,2,$align,$fill);
$i=($s[$sep]==' ') ? $sep+1 : $sep;
}
$sep=-1;
$j=$i;
$l=0;
$ns=0;
$nl++;
if($border と $nl==2)
$b=$b2;
}
それ以外
$i+=$ascii ? 1 : 2;
}
//最後のチャンク
if($this->ws>0)
{
$this->ws=0;
$this->_out('0 Tw');
}
if($border と is_int(strpos($border,'B')))
$b.='B';
$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
$this->x=$this->lマージン;
}
関数 Write($h,$txt,$link='')
{
if($this->CurrentFont['type']=='Type0')
$this->MBWrite($h,$txt,$link);
それ以外
親::書き込み($h,$txt,$link);
}
関数 MBWrite($h,$txt,$link)
{
//Write() のマルチバイトバージョン
$cw=&$this->現在のフォント['cw'];
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->フォントサイズ;
$s=str_replace("r",'',$txt);
$nb=strlen($s);
$sep=-1;
$i=0;
$j=0;
$l=0;
$nl=1;
while($i
{
//次のキャラクターを取得します
$c=$s[$i];
// ASCII か MB かを確認します
$ascii=(ord($c)
if($c=="n"
{
//明示的な改行
$this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
$i++;
$sep=-1;
$j=$i;
$l=0;
if($nl==1)
{
$this->x=$this->lマージン;
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->フォントサイズ;
}
$nl++;
続けます;
}
if(!$ascii または $c==' ')
$sep=$i;
$l+=$ascii ? $cw[$c] : 1000;
if($l>$wmax)
{
//自動改行
if($sep==-1 または $i==$j)
{
if($this->x>$this->lマージン)
{
//次の行に移動
$this->x=$this->lマージン;
$this->y+=$h;
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->フォントサイズ;
$i++;
$nl++;
続けます;
}
if($i==$j)
$i+=$ascii ? 1 : 2;
$this->Cell($w,$h,substr($s,$j,$i-$j),0,2,'',0,$link);
}
それ以外
{
$this->Cell($w,$h,substr($s,$j,$sep-$j),0,2,'',0,$link);
$i=($s[$sep]==' ') ? $sep+1 : $sep;
}
$sep=-1;
$j=$i;
$l=0;
if($nl==1)
{
$this->x=$this->lマージン;
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->フォントサイズ;
}
$nl++;
}
それ以外
$i+=$ascii ? 1 : 2;
}
//最後のチャンク
if($i!=$j)
$this->Cell($l/1000*$this->FontSize,$h,substr($s,$j,$i-$j),0,0,'',0,$link);
}
関数_putfonts()
{
$nf=$this->n;
foreach($this->diffs as $diff)
{
//エンコーディング
$this->_newobj();
$this->_out('<>');
$this->_out('endobj');
}
$mqr=get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
foreach($this->FontFiles as $file=>$info)
{
//フォントファイルの埋め込み
$this->_newobj();
$this->FontFiles[$file]['n']=$this->n;
if(定義('FPDF_FONTPATH'))
$file=FPDF_FONTPATH.$file;
$size=ファイルサイズ($file);
if(!$size)
$this->Error('フォント ファイルが見つかりません');
$this->_out('<
if(substr($file,-2)=='.z')
$this->_out('/Filter /FlateDecode');
$this->_out('/Length1 '.$info['length1']);
if(isset($info['length2']))
$this->_out('/Length2 '.$info['length2'].' /Length3 0');
$this->_out('>>');
$f=fopen($file,'rb');
$this->_putstream(fread($f,$size));
fclose($f);
$this->_out('endobj');
}
set_magic_quotes_runtime($mqr);
foreach($this->fonts as $k=>$font)
{
//フォントオブジェクト
$this->_newobj();
$this->fonts[$k]['n']=$this->n;
$this->_out('<
if($font['type']=='Type0')
$this->_putType0($font);
それ以外
{
$name=$font['name'];
$this->_out('/BaseFont /'.$name);
if($font['type']=='core')
{
//標準フォント
$this->_out('/Subtype /Type1');
if($name!='シンボル' および $name!='ZapfDingbats')
$this->_out('/Encoding /WinAnsiEncoding');
}
それ以外
{
//追加のフォント
$this->_out('/Subtype /'.$font['type']);
$this->_out('/FirstChar 32');
$this->_out('/LastChar 255');
$this->_out('/Widths '.($this->n+1).' 0 R');
$this->_out('/FontDescriptor '.($this->n+2).' 0 R');
if($font['enc'])
{
if(isset($font['diff']))
$this->_out('/Encoding '.($nf+$font['diff']).' 0 R');
それ以外
$this->_out('/Encoding /WinAnsiEncoding');
}
}
$this->_out('>>');
$this->_out('endobj');
if($font['type']!='core')
{
//幅
$this->_newobj();
$cw=&$font['cw'];
$s='[';
for($i=32;$i
$s.=$cw[chr($i)].' ';
$this->_out($s.']');
$this->_out('endobj');
//記述子
$this->_newobj();
$s='<
foreach($font['desc'] as $k=>$v)
$s.=' /'.$k.' '.$v;
$file=$font['ファイル'];
if($file)
$s.=' /FontFile'.($font['type']=='Type1' ? '' : '2').' '.$this->FontFiles[$file]['n'].' 0R';
$this->_out($s.'>>');
$this->_out('endobj');
}
}
}
}
関数_putType0($font)
{
//タイプ0
$this->_out('/Subtype /Type0');
$this->_out('/BaseFont /'.$font['name'].'-'.$font['CMap']);
$this->_out('/Encoding /'.$font['CMap']);
$this->_out('/DescendantFonts ['.($this->n+1).' 0 R]');
$this->_out('>>');
$this->_out('endobj');
//CIDFont
$this->_newobj();
$this->_out('<
$this->_out('/Subtype /CIDFontType0');
$this->_out('/BaseFont /'.$font['name']);
$this->_out('/CIDSystemInfo <レジストリ (Adobe) /Ordering ('.$font['registry']['ordering'].') /Supplement '.$font['registry'] ['補足'].'>>');
$this->_out('/FontDescriptor '.($this->n+1).' 0 R');
$W='/W [1 [';
foreach($font['cw'] as $w)
$W.=$w.' ';
$this->_out($W.']]');
$this->_out('>>');
$this->_out('endobj');
//フォント記述子
$this->_newobj();
$this->_out('<
$this->_out('/FontName /'.$font['name']);
$this->_out('/Flags 6');
$this->_out('/FontBBox [0 0 1000 1000]');
$this->_out('/ItalicAngle 0');
$this->_out('/Ascent 1000');
$this->_out('/Descent 0');
$this->_out('/CapHeight 1000');
$this->_out('/StemV 10');
$this->_out('>>');
$this->_out('endobj');
}
}
?>
参照用に、上記のコードを chinese.php として保存します。ただし、取得できるフォントは 1 つだけです。すべての中国語フォントをサポートするには、ttf2pt1 プログラムを使用して TrueType フォントを pt1 フォントに 1 つずつ変換できます (具体的な方法については、FPDF チュートリアルで詳しく説明されています)。他の中国語フォントをサポートするには、上記の chinese.php を次のように変更する必要があります。
1: AddGBFont() メソッド内の次の行を置き換えます。
function AddGBFont($family='GB',$name='STSongStd-Light-Acro')
{
$cw=$GLOBALS['GB_widths']
// $name='STSongStd-Light-Acro';
$CMap='GBKp-EUC-H';
……
2: これはサンプルです。
require('chinese.php');
$pdf=新しいPDF_中国語()
上記では、PHP を使用して PDF 中国語ドキュメントを作成する方法を、関連コンテンツも含めて紹介しました。PHP チュートリアルに興味のある友人に役立つことを願っています。