I am using FPDF to generate order invoice to customer, so far everything is working fine, except of some of our item name are mixed with Chinese text, and the output is somehow becoming alien's wording, as attached screenshot:
Script to generate PDF invoice:
<?php
require('fpdf.php');
//function hex2dec
//returns an associative array (keys: R,G,B) from a hex html code (e.g. #3FE5AA)
function hex2dec($couleur = "#000000"){
$R = substr($couleur, 1, 2);
$rouge = hexdec($R);
$V = substr($couleur, 3, 2);
$vert = hexdec($V);
$B = substr($couleur, 5, 2);
$bleu = hexdec($B);
$tbl_couleur = array();
$tbl_couleur['R']=$rouge;
$tbl_couleur['G']=$vert;
$tbl_couleur['B']=$bleu;
return $tbl_couleur;
}
//conversion pixel -> millimeter in 72 dpi
function px2mm($px){
return $px*25.4/72;
}
function txtentities($html){
$trans = get_html_translation_table(HTML_ENTITIES);
$trans = array_flip($trans);
return strtr($html, $trans);
}
class PDF extends FPDF
{
//variables of html parser
protected $B;
protected $I;
protected $U;
protected $HREF;
protected $fontList;
protected $issetfont;
protected $issetcolor;
function __construct($orientation='P', $unit='mm', $format='A4')
{
//Call parent constructor
parent::__construct($orientation,$unit,$format);
//Initialization
$this->B=0;
$this->I=0;
$this->U=0;
$this->HREF='';
$this->tableborder=0;
$this->tdbegin=false;
$this->tdwidth=0;
$this->tdheight=0;
$this->tdalign="L";
$this->tdbgcolor=false;
$this->oldx=0;
$this->oldy=0;
$this->fontlist=array("arial","times","courier","helvetica","symbol");
$this->issetfont=false;
$this->issetcolor=false;
}
//////////////////////////////////////
//html parser
function WriteHTML($html)
{
$html=strip_tags($html,"<b><u><i><a><img><p><br><strong><em><font><tr><blockquote><hr><td><tr><table><sup>"); //remove all unsupported tags
$html=str_replace("\n",'',$html); //replace carriage returns with spaces
$html=str_replace("\t",'',$html); //replace carriage returns with spaces
$a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE); //explode the string
foreach($a as $i=>$e)
{
if($i%2==0)
{
//Text
if($this->HREF)
$this->PutLink($this->HREF,$e);
elseif($this->tdbegin) {
if(trim($e)!='' && $e!=" ") {
$this->Cell($this->tdwidth,$this->tdheight,$e,$this->tableborder,'',$this->tdalign,$this->tdbgcolor);
}
elseif($e==" ") {
$this->Cell($this->tdwidth,$this->tdheight,'',$this->tableborder,'',$this->tdalign,$this->tdbgcolor);
}
}
else
$this->Write(5,stripslashes(txtentities($e)));
}
else
{
//Tag
if($e[0]=='/')
$this->CloseTag(strtoupper(substr($e,1)));
else
{
//Extract attributes
$a2=explode(' ',$e);
$tag=strtoupper(array_shift($a2));
$attr=array();
foreach($a2 as $v)
{
if(preg_match('/([^=]*)=["\']?([^"\']*)/',$v,$a3))
$attr[strtoupper($a3[1])]=$a3[2];
}
$this->OpenTag($tag,$attr);
}
}
}
}
function OpenTag($tag, $attr)
{
//Opening tag
switch($tag){
case 'SUP':
if( !empty($attr['SUP']) ) {
//Set current font to 6pt
$this->SetFont('','',6);
//Start 125cm plus width of cell to the right of left margin
//Superscript "1"
$this->Cell(2,2,$attr['SUP'],0,0,'L');
}
break;
case 'TABLE': // TABLE-BEGIN
if( !empty($attr['BORDER']) ) $this->tableborder=$attr['BORDER'];
else $this->tableborder=0;
break;
case 'TR': //TR-BEGIN
break;
case 'TD': // TD-BEGIN
if( !empty($attr['WIDTH']) ) $this->tdwidth=($attr['WIDTH']/4);
else $this->tdwidth=40; // Set to your own width if you need bigger fixed cells
if( !empty($attr['HEIGHT']) ) $this->tdheight=($attr['HEIGHT']/6);
else $this->tdheight=6; // Set to your own height if you need bigger fixed cells
if( !empty($attr['ALIGN']) ) {
$align=$attr['ALIGN'];
if($align=='LEFT') $this->tdalign='L';
if($align=='CENTER') $this->tdalign='C';
if($align=='RIGHT') $this->tdalign='R';
}
else $this->tdalign='R'; // Set to your own
if( !empty($attr['BGCOLOR']) ) {
$coul=hex2dec($attr['BGCOLOR']);
$this->SetFillColor($coul['R'],$coul['G'],$coul['B']);
$this->tdbgcolor=true;
}
$this->tdbegin=true;
break;
case 'HR':
if( !empty($attr['WIDTH']) )
$Width = $attr['WIDTH'];
else
$Width = $this->w - $this->lMargin-$this->rMargin;
$x = $this->GetX();
$y = $this->GetY();
$this->SetLineWidth(0.2);
$this->Line($x,$y,$x+$Width,$y);
$this->SetLineWidth(0.2);
$this->Ln(1);
break;
case 'STRONG':
$this->SetStyle('B',true);
break;
case 'EM':
$this->SetStyle('I',true);
break;
case 'B':
case 'I':
case 'U':
$this->SetStyle($tag,true);
break;
case 'A':
$this->HREF=$attr['HREF'];
break;
case 'IMG':
if(isset($attr['SRC']) && (isset($attr['WIDTH']) || isset($attr['HEIGHT']))) {
if(!isset($attr['WIDTH']))
$attr['WIDTH'] = 0;
if(!isset($attr['HEIGHT']))
$attr['HEIGHT'] = 0;
$this->Image($attr['SRC'], $this->GetX(), $this->GetY(), px2mm($attr['WIDTH']), px2mm($attr['HEIGHT']));
}
break;
case 'BLOCKQUOTE':
case 'BR':
$this->Ln(5);
break;
case 'P':
$this->Ln(10);
break;
case 'FONT':
if (isset($attr['COLOR']) && $attr['COLOR']!='') {
$coul=hex2dec($attr['COLOR']);
$this->SetTextColor($coul['R'],$coul['G'],$coul['B']);
$this->issetcolor=true;
}
if (isset($attr['FACE']) && in_array(strtolower($attr['FACE']), $this->fontlist)) {
$this->SetFont(strtolower($attr['FACE']));
$this->issetfont=true;
}
if (isset($attr['FACE']) && in_array(strtolower($attr['FACE']), $this->fontlist) && isset($attr['SIZE']) && $attr['SIZE']!='') {
$this->SetFont(strtolower($attr['FACE']),'',$attr['SIZE']);
$this->issetfont=true;
}
break;
}
}
function CloseTag($tag)
{
//Closing tag
if($tag=='SUP') {
}
if($tag=='TD') { // TD-END
$this->tdbegin=false;
$this->tdwidth=0;
$this->tdheight=0;
$this->tdalign="L";
$this->tdbgcolor=false;
}
if($tag=='TR') { // TR-END
$this->Ln();
}
if($tag=='TABLE') { // TABLE-END
$this->tableborder=0;
}
if($tag=='STRONG')
$tag='B';
if($tag=='EM')
$tag='I';
if($tag=='B' || $tag=='I' || $tag=='U')
$this->SetStyle($tag,false);
if($tag=='A')
$this->HREF='';
if($tag=='FONT'){
if ($this->issetcolor==true) {
$this->SetTextColor(0);
}
if ($this->issetfont) {
$this->SetFont('arial');
$this->issetfont=false;
}
}
}
function SetStyle($tag, $enable)
{
//Modify style and select corresponding font
$this->$tag+=($enable ? 1 : -1);
$style='';
foreach(array('B','I','U') as $s) {
if($this->$s>0)
$style.=$s;
}
$this->SetFont('',$style);
}
function PutLink($URL, $txt)
{
//Put a hyperlink
$this->SetTextColor(0,0,255);
$this->SetStyle('U',true);
$this->Write(5,$txt,$URL);
$this->SetStyle('U',false);
$this->SetTextColor(0);
}
// Page header
function Header()
{
// Logo
$this->Image(logo-mono.jpg',10,10,30);
$this->SetFont('Arial','B',15);
$this->Cell(138);
$this->Cell(70,5,'TAX INVOICE',0,0,'C');
$this->Ln(12);
// Company Header
$this->SetFont('Arial','B',9);
$this->Cell(0,5,'ABC COMPANY (1063511-D)',0,0,'L');
$this->Ln(0);
// Line break
$this->Ln(15);
}
// Page footer
function Footer()
{
// Position at 1.5 cm from bottom
$this->SetY(-15);
// Arial italic 8
$this->SetFont('Arial','I',8);
// Page number
$this->Cell(0,10,'Page '.$this->PageNo().'/{nb}',0,0,'C');
}
}
//Fetching specific order data and prepare an invoice
$invoice = $buyer->get_completed_transaction(
filter_var('1466404785-0J2XQR',FILTER_SANITIZE_STRING),
filter_var('T108869482600',FILTER_SANITIZE_STRING),
filter_var('LG6j3DYQbnylAFdaSdzcx5J0SYo=',FILTER_SANITIZE_STRING),
$mysqli
);
if($invoice !== FALSE){
//Checkout with BRP+CASH or CASH only, 2=BRP+CASH.
$checkout_method = $invoice->checkout_method;
//GENERATE INVOICE
$shipping_addr_1 = $invoice->shipping_address.',';
$shipping_addr_2 = $invoice->shipping_postcode.' '.$invoice->shipping_city.',';
$shipping_addr_3 = $invoice->shipping_province.' '.$invoice->shipping_country.'.';
// Instanciation of inherited class
$pdf = new PDF('P', 'mm', 'A4');
$pdf->AliasNbPages();
$pdf->AddPage();
$pdf->SetFont('Arial','B',9);
$pdf->setFillColor(230,230,230);
$pdf->Cell(50,5,'BILL TO',1,0,'L',1);
$pdf->Ln(3);
//
$pdf->SetFont('Arial','',9);
$pdf->Cell(0,15,strtoupper($invoice->recipient_name),0,0,'L');
$pdf->SetFont('Arial','B',8);
$pdf->Text(146,58,'DATE:');
$pdf->Text(146,63,'INVOICE #');
$pdf->Text(146,68,'CUSTOMER ID');
$pdf->SetFont('Arial','',8);
$pdf->Text(170,58,date('d/m/Y'));
$pdf->Text(170,63,$invoice->order_num);
$pdf->Ln(5);
$pdf->SetFont('Arial','',8);
$pdf->Cell(0,15,ucwords(strtolower($shipping_addr_1)),0,0,'L');
$pdf->Ln(5);
$pdf->Cell(0,15,ucwords(strtolower($shipping_addr_2)),0,0,'L');
$pdf->Ln(5);
$pdf->Cell(0,15,ucwords(strtolower($shipping_addr_3)),0,0,'L');
//
/*
$pdf->Ln(5);
$pdf->SetFont('Arial','B',8);
$pdf->Cell(10,25,'Tel:');
$pdf->SetFont('Arial','',8);
$pdf->Cell(0,25,$invoice->phone);
//
$pdf->Ln(5);
$pdf->SetFont('Arial','B',8);
$pdf->Cell(10,25,'Email:');
$pdf->SetFont('Arial','',8);
$pdf->Cell(118,25,$invoice->email);
*/
//
$pdf->Ln(14);
$pdf->SetFont('Arial','',8);
$html = '
<table border="1">
<tr>
<td width="30" height="30" bgcolor="#dddddd" align="left">No</td>
<td width="90" height="30" bgcolor="#dddddd" align="left">Item Code</td>
<td width="380" height="30" bgcolor="#dddddd" align="left">Descriptions</td>
<td width="40" height="30" bgcolor="#dddddd">Qty</td>
<td width="100" height="30" bgcolor="#dddddd">Price/Unit</td>
<td width="120" height="30" bgcolor="#dddddd">Amount</td>
</tr>';
$i = 1;
$shipping_rate = SHIPPING_RATE_ALL;
$total_payment = 0;
//Loop order items
$items = unserialize($invoice->cart_item);
foreach($items as $item){
//$keys = array_keys($item);
//$matches = preg_grep('~^p_alt\-variation\-\d+~i', $keys);
$unit_price = ($checkout_method == 2) ? ($item['p_price']/2) : $item['p_price'];
$subtotal = ($checkout_method == 2) ? (($item['p_price']/2) * $item['p_qty']) : ($item['p_price'] * $item['p_qty']);
$html .= '
<tr>
<td width="30" height="30" align="left">'.$i.'</td>
<td width="90" height="30" align="left">'.$item['p_code'].'</td>
<td width="380" height="30" align="left">'.$item['p_name'].'</td>
<td width="40" height="30">'.$item['p_qty'].'</td>
<td width="100" height="30">'.number_format($unit_price, 2, '.', ',').'</td>
<td width="120" height="30">'.number_format($subtotal, 2, '.', ',').'</td>
</tr>';
$i++;
$gross_payment += $subtotal;
}
//End Loop
$html .= '
<tr>
<td width="30" height="30"> </td>
<td width="90" height="30"> </td>
<td width="380" height="30"> </td>
<td width="40" height="30"> </td>
<td width="100" height="30"> </td>
<td width="120" height="30"> </td>
</tr>
<tr>
<td width="30" height="30"> </td>
<td width="90" height="30"> </td>
<td width="380" height="30"> </td>
<td width="40" height="30"> </td>
<td width="100" height="30"> </td>
<td width="120" height="30"> </td>
</tr>
</table>';
$pdf->WriteHTML($html);
//
$pdf->Ln(2);
$pdf->SetFont('Arial','',8);
$pdf->Cell(156,5,'Subtotal',0,0,'R');
$pdf->Cell(8,5,'$',0,0,'R');
$pdf->Cell(0,5,number_format($gross_payment,2,'.',','),0,1,'R');
$pdf->Cell(0,5,'Thank you for your business',0,0,'L');
$pdf->Cell(-34,5,'Shipping Cost',0,0,'R');
$pdf->Cell(8,5,'$',0,0,'R');
$pdf->Cell(0,5,number_format($shipping_rate,2,'.',','),0,1,'R');
if($checkout_method == 2){
$pdf->Cell(156,5,'BRP Consume',0,0,'R');
$pdf->Cell(8,5,'-',0,0,'R');
$pdf->Cell(0,5,number_format($invoice->total_points_consume,0,'.',','),0,1,'R');
}
$pdf->Ln(1);
$pdf->Cell(125,0,'',0,0,'R');
$pdf->Cell(65,0,'',1,0,'R');
$pdf->Ln(1);
$pdf->SetFont('Arial','B',8);
$pdf->Cell(156,10,'Total Including GST',0,0,'R');
$pdf->Cell(8,10,'$',0,0,'R',1);
$pdf->Cell(0,10,number_format($gst+$gross_payment+$shipping_rate,2,'.',','),0,1,'R',1);
$pdf->Ln(1);
//GST calculation
$gst = round((($gross_payment+$shipping_rate)*6.00)/100, 1);
$pdf->SetFont('Arial','',8);
$pdf->SetTextColor('88','88','88');
$pdf->Cell(156,5,'GST 6%',0,0,'R');
$pdf->Cell(8,5,'$',0,0,'R');
$pdf->Cell(0,5,number_format($gst,2,'.',','),0,1,'R');
$pdf->Ln(1);
//
$pdf->Ln(10);
//$pdf->WriteHTML('<HR>');
$pdf->SetFont('Arial','B',8);
$pdf->Cell(90,5,'ABC COMPANY',0,0,'L',0);
$pdf->Ln(20);
$pdf->Cell(50,0,'',1,1,'L',0);
$pdf->Ln(1);
$pdf->SetFont('Arial','BI',8);
$pdf->Cell(90,5,'Authorised Signature',0,0,'L',0);
$path = '/invoice/';
$file = $invoice->order_num.'.pdf';
$pdf->Output();
}
?>
I've been look for the solution around and tried with tFPDF, I get error with
Fatal error: Call to undefined method tFPDF::WriteHTML() in C:\pathto\create_invoice_test.php on line 448
I have no idea of how to implement it into current scripts, I need workaround to solve this issue.