2016-04-15 17 views
1

Ich verwende FPDF, um Tabellen zu rendern, die innerhalb des HTML-Inhalts sind. So wie ich Tabellen rendern wollte, bekam ich diese link, um die Tabelle zu rendern. Die Sache ist, ich habe zwei Tabellen nacheinander im HTML und ich kann es nicht trennen, da der Inhalt durch WYSIWYG Editor kommt. Hier für den ersten Tisch funktioniert es gut. Aber für die zweite Tabelle funktioniert es überhaupt nicht. Ich habe alle Markups überprüft und alles sieht gut aus.FPDF WriteHTML() mehrere Tabellen-Rendering zeigt nur die erste korrekt

html_table.php ist wie dieser

<?php 
//Based on HTML2PDF by Clément Lavoillotte 


require('fpdf/fpdf.php'); 
require('htmlparser.inc.php'); 

class PDF_HTML_Table extends FPDF 
{ 
var $B; 
var $I; 
var $U; 
var $HREF; 

function PDF($orientation='P', $unit='mm', $format='A4') 
{ 
    //Call parent constructor 
    $this->FPDF($orientation,$unit,$format); 
    //Initialization 
    $this->B=0; 
    $this->I=0; 
    $this->U=0; 
    $this->HREF=''; 
} 

function WriteHTML2($html) 
{ 
    //HTML parser 
    $html=str_replace("\n",' ',$html); 
    $a=preg_split('/<(.*)>/U',$html,-1,PREG_SPLIT_DELIM_CAPTURE); 
    foreach($a as $i=>$e) 
    { 
     if($i%2==0) 
     { 
      //Text 
      if($this->HREF) 
       $this->PutLink($this->HREF,$e); 
      else 
       $this->Write(5,$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 
    if($tag=='B' || $tag=='I' || $tag=='U') 
     $this->SetStyle($tag,true); 
    if($tag=='A') 
     $this->HREF=$attr['HREF']; 
    if($tag=='BR') 
     $this->Ln(5); 
    if($tag=='P') 
     $this->Ln(10); 
} 

function CloseTag($tag) 
{ 
    //Closing tag 
    if($tag=='B' || $tag=='I' || $tag=='U') 
     $this->SetStyle($tag,false); 
    if($tag=='A') 
     $this->HREF=''; 
    if($tag=='P') 
     $this->Ln(10); 
} 

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); 
} 

function WriteTable($data, $w) 
{ 
    $this->SetLineWidth(.3); 
    $this->SetFillColor(255,255,255); 
    $this->SetTextColor(0); 
    $this->SetFont(''); 
    foreach($data as $row) 
    { 
     $nb=0; 
     for($i=0;$i<count($row);$i++) 
      $nb=max($nb,$this->NbLines($w[$i],trim($row[$i]))); 
     $h=5*$nb; 
     $this->CheckPageBreak($h); 
     for($i=0;$i<count($row);$i++) 
     { 
      $x=$this->GetX(); 
      $y=$this->GetY(); 
      $this->Rect($x,$y,$w[$i],$h); 
      $this->MultiCell($w[$i],5,trim($row[$i]),0,'C'); 
      //Put the position to the right of the cell 
      $this->SetXY($x+$w[$i],$y);      
     } 
     $this->Ln($h); 

    } 
} 

function NbLines($w, $txt) 
{ 
    //Computes the number of lines a MultiCell of width w will take 
    $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("\r",'',$txt); 
    $nb=strlen($s); 
    if($nb>0 && $s[$nb-1]=="\n") 
     $nb--; 
    $sep=-1; 
    $i=0; 
    $j=0; 
    $l=0; 
    $nl=1; 
    while($i<$nb) 
    { 
     $c=$s[$i]; 
     if($c=="\n") 
     { 
      $i++; 
      $sep=-1; 
      $j=$i; 
      $l=0; 
      $nl++; 
      continue; 
     } 
     if($c==' ') 
      $sep=$i; 
     $l+=$cw[$c]; 
     if($l>$wmax) 
     { 
      if($sep==-1) 
      { 
       if($i==$j) 
        $i++; 
      } 
      else 
       $i=$sep+1; 
      $sep=-1; 
      $j=$i; 
      $l=0; 
      $nl++; 
     } 
     else 
      $i++; 
    } 
    return $nl; 
} 

function CheckPageBreak($h) 
{ 
    //If the height h would cause an overflow, add a new page immediately 
    if($this->GetY()+$h>$this->PageBreakTrigger) 
     $this->AddPage($this->CurOrientation); 
} 

function ReplaceHTML($html) 
{ 
    $html = str_replace('<li>', "\n<br> - " , $html); 
    $html = str_replace('<LI>', "\n - " , $html); 
    $html = str_replace('</ul>', "\n\n" , $html); 
    $html = str_replace('<strong>', "<b>" , $html); 
    $html = str_replace('</strong>', "</b>" , $html); 
    $html = str_replace('&#160;', "\n" , $html); 
    $html = str_replace('&nbsp;', " " , $html); 
    $html = str_replace('&quot;', "\"" , $html); 
    $html = str_replace('&#39;', "'" , $html); 
    return $html; 
} 

function ParseTable($Table) 
{ 
    $_var=''; 
    $htmlText = $Table; 
    $parser = new HtmlParser ($htmlText); 
    while ($parser->parse()) 
    { 
     if(strtolower($parser->iNodeName)=='table') 
     { 
      if($parser->iNodeType == NODE_TYPE_ENDELEMENT) 
       $_var .='/::'; 
      else 
       $_var .='::'; 
     } 

     if(strtolower($parser->iNodeName)=='tr') 
     { 
      if($parser->iNodeType == NODE_TYPE_ENDELEMENT) 
       $_var .='!-:'; //opening row 
      else 
       $_var .=':-!'; //closing row 
     } 
     if(strtolower($parser->iNodeName)=='td' && $parser->iNodeType == NODE_TYPE_ENDELEMENT) 
     { 
      $_var .='#,#'; 
     } 
     if ($parser->iNodeName=='Text' && isset($parser->iNodeValue)) 
     { 
      $_var .= $parser->iNodeValue; 
     } 
    } 
    $elems = explode(':-!',str_replace('/','',str_replace('::','',str_replace('!-:','',$_var)))); //opening row 
    foreach($elems as $key=>$value) 
    { 
     if(trim($value)!='') 
     { 
      $elems2 = explode('#,#',$value); 
      array_pop($elems2); 
      $data[] = $elems2; 
     } 
    } 
    return $data; 
} 

function WriteHTML($html) 
{ 
    $html = $this->ReplaceHTML($html); 
    //Search for a table 
    $start = strpos(strtolower($html),'<table'); 
    $end = strpos(strtolower($html),'</table'); 
    if($start!==false && $end!==false) 
    { 
     $this->WriteHTML2(substr($html,0,$start).'<BR>'); 

     $tableVar = substr($html,$start,$end-$start); 
     $tableData = $this->ParseTable($tableVar); 
     for($i=1;$i<=count($tableData[0]);$i++) 
     { 
      if($this->CurOrientation=='L') 
       $w[] = abs(120/(count($tableData[0])-1))+24; 
      else 
       $w[] = abs(120/(count($tableData[0])-1))+5; 
     } 
     $this->WriteTable($tableData,$w); 

     $this->WriteHTML2(substr($html,$end+8,strlen($html)-1).'<BR>'); 
    } 
    else 
    { 
     $this->WriteHTML2($html); 
    } 
} 

} 

und die index.php ist wie folgt

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

$pdf = new PDF_HTML_Table(); 
$pdf->AddPage(); 
$pdf->SetFont('Arial','',12); 

$html='<table border="1"> 
<tr> 
<td width="200" height="30">cell 1</td><td width="200" height="30" bgcolor="#D0D0FF">cell 2</td> 
</tr> 
<tr> 
<td width="200" height="30">cell 3</td><td width="200" height="30">cell 4</td> 
</tr> 
</table> 
<br> 
<br> 
<table border="1"> 
<tr> 
<td width="200" height="30">cell 5</td><td width="200" height="30" bgcolor="#D0D0FF">cell 6</td> 
</tr> 
<tr> 
<td width="200" height="30">cell 7</td><td width="200" height="30">cell 8</td> 
</tr> 
</table> 
'; 

$pdf->WriteHTML($html); 
$pdf->Output(); 
?> 

Kann mir jemand sagen, wie dieses Problem zu lösen? Jede Hilfe und Vorschläge werden wirklich spürbar sein. Dank

Antwort

0

Ich hatte genau dieses Problem den anderen Tag, und kam mit der folgenden Lösung:

  1. In Ihrer FPDF Klasse, fügen Sie eine Funktion findAll(). Dies wird verwendet werden, um alle Instanzen von <table und </table in Ihrem HTML zu finden zu konvertieren:

    function findAll($needle, $haystack) 
    { 
        // initialize the return value array 
        $rv = array(); 
    
        // set up a temp variable to make things simple 
        $temp = 0; 
    
        // successively find each instance of needle in haystack 
        while($temp < strlen($haystack)) 
        { 
        $temp = strpos($haystack,$needle, $temp); 
    
        if($temp !== false) 
        { 
         $rv[] = $temp; 
         $temp++; 
        } 
        else 
        { 
         // nothing to find 
         return $rv; 
        } 
        } 
    
        return $rv; 
    } 
    
  2. ändern Sie bitte Ihre WriteHTML() Funktion a) verwenden findAll() alle Tabellen Instanzen zu finden, und b) ersetzt jeden (Beliebige Nicht-Tabellen-Formatierung intakt halten). Diese Modifikation im Wesentlichen „Chunks“ Ihr HTML-Code in „Tabelle“ und „Nicht-Tabelle“ Stücke und formatiert die HTML entsprechend:

    function WriteHTML($html) 
        { 
        $w = array(); 
    
        // search for a table 
        $starts = $this->findAll('<table',strtolower($html)); 
        $ends = $this->findAll('</table',strtolower($html)); 
    
        if(count($starts) > 0 && count($ends) > 0) 
        { 
         $positions[0] = 'doc-start'; 
    
         foreach($starts as $key => $start) 
         { 
         $end = $ends[$key]; 
         $positions[$start] = 'table-start'; 
         $positions[$end] = 'table-end'; 
         } 
    
         $endPos = strlen($html)-1; 
         $positions[$endPos] = 'doc-end'; 
    
         $lastKnownPos = 0; 
    
         for($q=1;$q<=$endPos;$q++) 
         { 
         if(isset($positions[$q])) 
         { 
          $curPos = $positions[$q]; 
    
          if($curPos == 'table-start') 
          { 
          $this->WriteHTML2(substr($html,$lastKnownPos,$q-$lastKnownPos).'<BR>'); 
          $lastKnownPos = $q; 
          } 
          else if($curPos == 'table-end') 
          { 
          $tableVar = substr($html,$lastKnownPos,$q-$lastKnownPos+8); 
          $tableData = $this->ParseTable($tableVar); 
    
          for($i=0;$i<count($tableData[0]);$i++) 
          { 
           if($this->CurOrientation=='L') 
           { 
           $w[$i] = abs(277/(count($tableData[0]))); 
           } 
           else 
           { 
           $w[$i] = abs(190/(count($tableData[0]))); 
           } 
          } 
          $this->WriteTable($tableData,$w); 
          $lastKnownPos = $q+8; 
          } 
          else if($curPos == 'doc-end') 
          { 
          $this->WriteHTML2(substr($html,$lastKnownPos,$q-$lastKnownPos).'<BR>'); 
          $lastKnownPos = $q;    
          } 
         } 
         } 
        } 
        else 
        { 
         // if there is no table, just write the HTML as normal 
         $this->WriteHTML2($html); 
        } 
        } 
    
1

Wenn Sie HTML-Code verwenden Tabellen für PDF-Dokumente zu erstellen generiert mit der FPDF-Bibliothek, dann werfen Sie einen Blick auf das FPDF easyTable-Projekt https://github.com/fpdf-easytable/fpdf-easytable

$table=new easyTable($pdf, 3, 'border:1;'); 

// first row 
$table->easyCell('Text 1', 'valign:T'); 
$table->easyCell('Text 2', 'bgcolor:#b3ccff;'); 
$table->easyCell('Text 3'); 
$table->printRow(); 

//second row 
$table->rowStyle('min-height:20; align:{C}'); 
$table->easyCell('Text 4', 'colspan:3'); 
$table->printRow(); 

$table->endTable(4); 
Verwandte Themen