Welcome 微信登录

首页 / 网页编程 / PHP / php创建PDF中文文档的程序代码

php创建PDF中文文档的程序代码2011-01-18我使用的是FPDF(www.fpdf.org),下载了fpdf类库后,还要使用下面的中文类库才能支持中文,但只能使用一种中文字体(华文仿宋)。为此我烦恼了很长时间,现在终于搞定了,将TrueType字体转化为pt1字体使用:

下面是在FPDF上找的一个中文类库:

<?php
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);
class PDF_Chinese extends FPDF
{
function AddCIDFont($family,$style,$name,$cw,$CMap,$registry)
{
$i=count($this->fonts)+1;
$fontkey=strtolower($family).strtoupper($style);
$this->fonts[$fontkey]=array("i"=>$i,"type"=>"Type0","name"=>$name,"up"=>-120,"ut"=>40,"cw"=>$cw,"CMap"=>$CMap,"registry"=>$registry);
}
function 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);
}
function 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);
}
function GetStringWidth($s)
{
if($this->CurrentFont["type"]=="Type0")
return $this->GetMBStringWidth($s);
else
return parent::GetStringWidth($s);
}
function GetMBStringWidth($s)
{
//Multi-byte version of GetStringWidth()
$l=0;
$cw=&$this->CurrentFont["cw"];
$nb=strlen($s);
$i=0;
while($i<$nb)
{
$c=$s[$i];
if(ord($c)<128)
{
$l+=$cw[$c];
$i++;
}
else
{
$l+=1000;
$i+=2;
}
}
return $l*$this->FontSize/1000;
}
function MultiCell($w,$h,$txt,$border=0,$align="L",$fill=0)
{
if($this->CurrentFont["type"]=="Type0")
$this->MBMultiCell($w,$h,$txt,$border,$align,$fill);
else
parent::MultiCell($w,$h,$txt,$border,$align,$fill);
}
function MBMultiCell($w,$h,$txt,$border=0,$align="L",$fill=0)
{
//Multi-byte version of MultiCell()
$cw=&$this->CurrentFont["cw"];
if($w==0)
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
$s=str_replace(" ","",$txt);
$nb=strlen($s);
if($nb>0 and $s[$nb-1]==" "
$nb--;
$b=0;
if($border)
{
if($border==1)
{
$border="LTRB";
$b="LRT";
$b2="LR";
}
else
{
$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<$nb)
{
//Get next character
$c=$s[$i];
//Check if ASCII or MB
$ascii=(ord($c)<128);
if($c==" "
{
//Explicit line break
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 and $nl==2)
$b=$b2;
continue;
}
if(!$ascii)
{
$sep=$i;
$ls=$l;
}
elseif($c==" ")
{
$sep=$i;
$ls=$l;
$ns++;
}
$l+=$ascii ? $cw[$c] : 1000;
if($l>$wmax)
{
//Automatic line break
if($sep==-1 or $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);
}
else
{
if($align=="J")
{
if($s[$sep]==" ")
$ns--;
if($s[$i-1]==" ")
{
$ns--;
$ls-=$cw[" "];
}
$this->ws=($ns>0) ? ($wmax-$ls)/1000*$this->FontSize/$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 and $nl==2)
$b=$b2;
}
else
$i+=$ascii ? 1 : 2;
}
//Last chunk
if($this->ws>0)
{
$this->ws=0;
$this->_out("0 Tw");
}
if($border and is_int(strpos($border,"B")))
$b.="B";
$this->Cell($w,$h,substr($s,$j,$i-$j),$b,2,$align,$fill);
$this->x=$this->lMargin;
}
function Write($h,$txt,$link="")
{
if($this->CurrentFont["type"]=="Type0")
$this->MBWrite($h,$txt,$link);
else
parent::Write($h,$txt,$link);
}
function MBWrite($h,$txt,$link)
{
//Multi-byte version of Write()
$cw=&$this->CurrentFont["cw"];
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
$s=str_replace(" ","",$txt);
$nb=strlen($s);
$sep=-1;
$i=0;
$j=0;
$l=0;
$nl=1;
while($i<$nb)
{
//Get next character
$c=$s[$i];
//Check if ASCII or MB
$ascii=(ord($c)<128);
if($c==" "
{
//Explicit line break
$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->lMargin;
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
}
$nl++;
continue;
}
if(!$ascii or $c==" ")
$sep=$i;
$l+=$ascii ? $cw[$c] : 1000;
if($l>$wmax)
{
//Automatic line break
if($sep==-1 or $i==$j)
{
if($this->x>$this->lMargin)
{
//Move to next line
$this->x=$this->lMargin;
$this->y+=$h;
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
$i++;
$nl++;
continue;
}
if($i==$j)
$i+=$ascii ? 1 : 2;
$this->Cell($w,$h,substr($s,$j,$i-$j),0,2,"",0,$link);
}
else
{
$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->lMargin;
$w=$this->w-$this->rMargin-$this->x;
$wmax=($w-2*$this->cMargin)*1000/$this->FontSize;
}
$nl++;
}
else
$i+=$ascii ? 1 : 2;
}
//Last chunk
if($i!=$j)
$this->Cell($l/1000*$this->FontSize,$h,substr($s,$j,$i-$j),0,0,"",0,$link);
}
function _putfonts()
{
$nf=$this->n;
foreach($this->diffs as $diff)
{
//Encodings
$this->_newobj();
$this->_out("<</Type /Encoding /BaseEncoding /WinAnsiEncoding /Differences [".$diff."]>>");
$this->_out("endobj");
}
$mqr=get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
foreach($this->FontFiles as $file=>$info)
{
//Font file embedding
$this->_newobj();
$this->FontFiles[$file]["n"]=$this->n;
if(defined("FPDF_FONTPATH"))
$file=FPDF_FONTPATH.$file;
$size=filesize($file);
if(!$size)
$this->Error("Font file not found");
$this->_out("<</Length ".$size);
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)
{
//Font objects
$this->_newobj();
$this->fonts[$k]["n"]=$this->n;
$this->_out("<</Type /Font");
if($font["type"]=="Type0")
$this->_putType0($font);
else
{
$name=$font["name"];
$this->_out("/BaseFont /".$name);
if($font["type"]=="core")
{
//Standard font
$this->_out("/Subtype /Type1");
if($name!="Symbol" and $name!="ZapfDingbats")
$this->_out("/Encoding /WinAnsiEncoding");
}
else
{
//Additional font
$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");
else
$this->_out("/Encoding /WinAnsiEncoding");
}
}
$this->_out(">>");
$this->_out("endobj");
if($font["type"]!="core")
{
//Widths
$this->_newobj();
$cw=&$font["cw"];
$s="[";
for($i=32;$i<=255;$i++)
$s.=$cw[chr($i)]." ";
$this->_out($s."]");
$this->_out("endobj");
//Descriptor
$this->_newobj();
$s="<</Type /FontDescriptor /FontName /".$name;
foreach($font["desc"] as $k=>$v)
$s.=" /".$k." ".$v;
$file=$font["file"];
if($file)
$s.=" /FontFile".($font["type"]=="Type1" ? "" : "2")." ".$this->FontFiles[$file]["n"]." 0 R";
$this->_out($s.">>");
$this->_out("endobj");
}
}
}
}
function _putType0($font)
{
//Type0
$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("<</Type /Font");
$this->_out("/Subtype /CIDFontType0");
$this->_out("/BaseFont /".$font["name"]);
$this->_out("/CIDSystemInfo <</Registry (Adobe) /Ordering (".$font["registry"]["ordering"].") /Supplement ".$font["registry"]["supplement"].">>");
$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");
//Font descriptor
$this->_newobj();
$this->_out("<</Type /FontDescriptor");
$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");
}
}
?>