Erweiterte Tabellen mit FPDF

FPDF ist eine kostenlose PHP Library zum Erzeugen von PDF Dokumenten mit PHP (z.B. Rechnungen mit FPDF erzeugen). Mit Hilfe der Cell und MultiCell Funktionen ist es möglich Tabellen zu erzeugen, allerdings ist dies immer mit viel Aufwand verbunden. Unter den FPDF Addons gibt es einige Ansätze für das Arbeiten mit Tabellen. Ich habe mir die Lösung von Olivier herausgesucht und diese für unsere Bedürfnisse angepasst und stark erweitert. Da diese Lösung garantiert für andere Programmierer interessant ist, die Rechnungen, Mahnungen und andere Belege (Dokumente mit Tabellen) erzeugen, wird sie hier veröffentlicht. Anhand von Arrays wird das Design für einzelne Cellen festgelegt. Mehrere Cellen ergeben eine Zeile. Diese Infos werden einer Funktion übergeben, die daraus eine Tabelle generiert. Um das Erzeugen der Tabellen mit Cell oder MultiCell muss der Programmierer sich nicht mehr kümmern. Die Lösung basiert auf MultiCell, damit eine Celle auch aus mehreren Zeilen bestehen kann.

Funktionen

Das gleich kommende Beispiel erzeugt eine Tabelle die so ausschaut:

Tabellen Beispiel

PHP Code zum erzeugen der Tabelle
<?php
// create pdf
$pdf=new MYPDF('P','mm','A4');
$pdf->AliasNbPages();
$pdf->SetMargins($pdf->left$pdf->top$pdf->right); 
$pdf->AddPage();
   
// create table
$columns = array();      
   
// header col
$col = array();
$col[] = array('text' => 'Datum''width' => '20''height' => '5''align' => 'C''font_name' => 'Arial''font_size' => '8''font_style' => 'B''fillcolor' => '135,206,250''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Text''width' => '125''height' => '5''align' => 'C''font_name' => 'Arial''font_size' => '8''font_style' => 'B''fillcolor' => '135,206,250''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Soll''width' => '15''height' => '5''align' => 'C''font_name' => 'Arial''font_size' => '8''font_style' => 'B''fillcolor' => '135,206,250''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Haben''width' => '15''height' => '5''align' => 'C''font_name' => 'Arial''font_size' => '8''font_style' => 'B''fillcolor' => '135,206,250''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Saldo''width' => '15''height' => '5''align' => 'C''font_name' => 'Arial''font_size' => '8''font_style' => 'B''fillcolor' => '135,206,250''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');   
$columns[] = $col;
   
// data col
$col = array();
$col[] = array('text' => '01.12.2010''width' => '20''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Rechnungs Nr 123456789''width' => '125''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => '120.50''width' => '15''height' => '5''align' => 'R''font_name' => 'Arial''font_size' => '12''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => '''width' => '15''height' => '5''align' => 'R''font_name' => 'Arial''font_size' => '8''font_style' => 'B''fillcolor' => '255,255,255''textcolor' => '0,0,255''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => '120.50S''width' => '15''height' => '5''align' => 'R''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');       
$columns[] = $col;
 
// data col
$col = array();
$col[] = array('text' => '15.12.2010''width' => '20''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Zahlung: 123456789''width' => '125''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => '''width' => '15''height' => '5''align' => 'R''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => '120.50''width' => '15''height' => '5''align' => 'R''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => '0.00H''width' => '15''height' => '5''align' => 'R''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');       
$columns[] = $col;

$col = array();
$col[] = array('text' => 'Ist der Text zu lang, ist das kein Problem''width' => '50''height' => '5''align' => 'R''font_name' => 'Arial''font_size' => '12''font_style' => '''fillcolor' => '0,0,255''textcolor' => '0,255,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Auch mit mehreren Farben ist es kein Problem''width' => '50''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => 'B''fillcolor' => '255,255,0''textcolor' => '0,255,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'So ist das Bauen einer Tabelle einfach nur einfach. MuliCell macht es einfach. Okay das ist nun lang genug''width' => '50''height' => '5''align' => 'C''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,255,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Erstellen von Rechnungen sind kein Problem mehr''width' => '40''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,0,255''textcolor' => '0,255,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$columns[] = $col;

$col = array();
$col[] = array('text' => 'Einfach nur mal eine Zeile ohne Rahmen''width' => '190''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,255,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'TB');
$columns[] = $col;

$col = array();
$col[] = array('text' => 'Einfach nur mal eine Zeile in der Tabelle''width' => '80''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,0,0''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$col[] = array('text' => 'Gerne auch mit einer Spalte mehr''width' => '110''height' => '5''align' => 'L''font_name' => 'Arial''font_size' => '8''font_style' => '''fillcolor' => '255,255,255''textcolor' => '0,0,0''drawcolor' => '0,0,0''linewidth' => '0.4''linearea' => 'LTBR');
$columns[] = $col;

// Draw Table   
$pdf->WriteTable($columns);
   
// Show PDF   
$pdf->Output();
?>

Die einzelnen Zellen werden bei Rechnungen und anderen Belegen natürlich über eine Schleife gefüllt. So ist es umständlich, soll aber nur als Beispiel dienen.

Dokumentation

Der Quellcode ist eigentlich selbst erklärend. Mehreren Zellen werdern in einem Array zu einer Zeile zusammengefasst, welche dann das Array für die Visualisierung darstellt und an die Funktion WriteTable übergeben wird. Das Array muss für jede Celle jeweils komplett gefüllt werden. Farben werden als RGB im CSV übergegeben. Linearea gibt an, ob linke, rechte, obere oder untere Rahmen angezeigt werden sollen. Alles andere sollte logisch sein. Ansonsten in den Beispielen etwas rumprobieren.

Anpassungen an der FPDF Klasse
<?php
// own pdf structure

class MYPDF extends FPDF
{
   
// Margins
   
var $left 10;
   var 
$right 10;
   var 
$top 10;
   var 
$bottom 10;
         
   
// Create Table
   
function WriteTable($tcolums)
   {
      
// go through all colums
      
for ($i 0$i sizeof($tcolums); $i++)
      {
         
$current_col $tcolums[$i];
         
$height 0;
         
         
// get max height of current col
         
$nb=0;
         for(
$b 0$b sizeof($current_col); $b++)
         {
            
// set style
            
$this->SetFont($current_col[$b]['font_name'], $current_col[$b]['font_style'], $current_col[$b]['font_size']);
            
$color explode(","$current_col[$b]['fillcolor']);
            
$this->SetFillColor($color[0], $color[1], $color[2]);
            
$color explode(","$current_col[$b]['textcolor']);
            
$this->SetTextColor($color[0], $color[1], $color[2]);            
            
$color explode(","$current_col[$b]['drawcolor']);            
            
$this->SetDrawColor($color[0], $color[1], $color[2]);
            
$this->SetLineWidth($current_col[$b]['linewidth']);
                        
            
$nb max($nb$this->NbLines($current_col[$b]['width'], $current_col[$b]['text']));            
            
$height $current_col[$b]['height'];
         }  
         
$h=$height*$nb;
         
         
         
// Issue a page break first if needed
         
$this->CheckPageBreak($h);
         
         
// Draw the cells of the row
         
for($b 0$b sizeof($current_col); $b++)
         {
            
$w $current_col[$b]['width'];
            
$a $current_col[$b]['align'];
            
            
// Save the current position
            
$x=$this->GetX();
            
$y=$this->GetY();
            
            
// set style
            
$this->SetFont($current_col[$b]['font_name'], $current_col[$b]['font_style'], $current_col[$b]['font_size']);
            
$color explode(","$current_col[$b]['fillcolor']);
            
$this->SetFillColor($color[0], $color[1], $color[2]);
            
$color explode(","$current_col[$b]['textcolor']);
            
$this->SetTextColor($color[0], $color[1], $color[2]);            
            
$color explode(","$current_col[$b]['drawcolor']);            
            
$this->SetDrawColor($color[0], $color[1], $color[2]);
            
$this->SetLineWidth($current_col[$b]['linewidth']);
            
            
$color explode(","$current_col[$b]['fillcolor']);            
            
$this->SetDrawColor($color[0], $color[1], $color[2]);
            
            
            
// Draw Cell Background
            
$this->Rect($x$y$w$h'FD');
            
            
$color explode(","$current_col[$b]['drawcolor']);            
            
$this->SetDrawColor($color[0], $color[1], $color[2]);
            
            
// Draw Cell Border
            
if (substr_count($current_col[$b]['linearea'], "T") > 0)
            {
               
$this->Line($x$y$x+$w$y);
            }            
            
            if (
substr_count($current_col[$b]['linearea'], "B") > 0)
            {
               
$this->Line($x$y+$h$x+$w$y+$h);
            }            
            
            if (
substr_count($current_col[$b]['linearea'], "L") > 0)
            {
               
$this->Line($x$y$x$y+$h);
            }
                        
            if (
substr_count($current_col[$b]['linearea'], "R") > 0)
            {
               
$this->Line($x+$w$y$x+$w$y+$h);
            }
            
            
            
// Print the text
            
$this->MultiCell($w$current_col[$b]['height'], $current_col[$b]['text'], 0$a0);
            
            
// Put the position to the right of the cell
            
$this->SetXY($x+$w$y);         
         }
         
         
// Go to the next line
         
$this->Ln($h);          
      }                  
   }

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


   
// Computes the number of lines a MultiCell of width w will take
   
function NbLines($w$txt)
   {
      
$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>and $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;
   }
        
}
?>

Das wars auch schon. Mein Text darf nicht auf anderen Seiten kopiert werden, aber Verlinkungen sind gerne willkommen. Der Quellcode ist Freeware, jeder kann es Nutzen und verändern wie er Lust hat. Viel Erfolg und ich hoffe ich konnte so einigen hiermit helfen.

© by von der Born, Hannover, Deutschland Kontakt | Datenschutz | Impressum