Table with MultiCells

Add-On Table with MultiCells

Informations

Author:Olivier
License: FPDF

Description

The goal of this script is to show how to build a table from MultiCells.
As MultiCells go to the next line after being output, the base idea consists in saving the current position, printing the MultiCell and resetting the position to its right.
There is a difficulty, however, if the table is too long: page breaks. Before outputting a row, it is necessary to know whether it will cause a break or not. If it does overflow, a manual page break must be done first.
To do so, the height of the row must be known in advance; it is the maximum of the heights of the MultiCells it is made up of. To know the height of a MultiCell, the NbLines() method is used: it returns the number of lines a MultiCell will occupy.

Source

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

class PDF_MC_Table extends FPDF
{
    protected $widths;
    protected $aligns;

    function SetWidths($w)
    {
        // Set the array of column widths
        $this->widths = $w;
    }

    function SetAligns($a)
    {
        // Set the array of column alignments
        $this->aligns = $a;
    }

    function Row($data)
    {
        // Calculate the height of the row
        $nb = 0;
        for($i=0;$i<count($data);$i++)
            $nb = max($nb, $this->NbLines($this->widths[$i], $data[$i]));
        $h = 5*$nb;
        // Issue a page break first if needed
        $this->CheckPageBreak($h);
        // Draw the cells of the row
        for($i=0;$i<count($data);$i++)
        {
            $w = $this->widths[$i];
            $a = isset($this->aligns[$i]) ? $this->aligns[$i] : 'L';
            // Save the current position
            $x = $this->GetX();
            $y = $this->GetY();
            // Draw the border
            $this->Rect($x, $y, $w, $h);
            // Print the text
            $this->MultiCell($w, 5, $data[$i], 0, $a);
            // Put the position to the right of the cell
            $this->SetXY($x+$w, $y);
        }
        // Go to the next line
        $this->Ln($h);
    }

    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 NbLines($w, $txt)
    {
        // Compute the number of lines a MultiCell of width w will take
        if(!isset($this->CurrentFont))
            $this->Error('No font has been set');
        $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", '', (string)$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;
    }
}
?>

Example

Here's an example of multi-page table with random content:
<?php
require('mc_table.php');

function GenerateWord()
{
    // Get a random word
    $nb = rand(3, 10);
    $w = '';
    for($i=1;$i<=$nb;$i++)
        $w .= chr(rand(ord('a'), ord('z')));
    return $w;
}

function GenerateSentence()
{
    // Get a random sentence
    $nb = rand(1, 10);
    $s = '';
    for($i=1;$i<=$nb;$i++)
        $s .= GenerateWord().' ';
    return substr($s, 0, -1);
}

$pdf = new PDF_MC_Table();
$pdf->AddPage();
$pdf->SetFont('Arial', '', 14);
// Table with 20 rows and 4 columns
$pdf->SetWidths(array(30, 50, 30, 40));
for($i=0;$i<20;$i++)
    $pdf->Row(array(GenerateSentence(), GenerateSentence(), GenerateSentence(), GenerateSentence()));
$pdf->Output();
?>
View the result here.

Download

ZIP | TGZ
Es ist ein Fehler aufgetreten

Es ist ein Fehler aufgetreten

Was ist das Problem?

Bei der Ausführung des Skriptes ist ein Fehler aufgetreten. Irgendetwas funktioniert nicht richtig.

Wie kann ich das Problem lösen?

Öffnen Sie die aktuelle Log-Datei im Ordner var/logs bzw. app/logs und suchen Sie die zugehörige Fehlermeldung (normalerweise die letzte).

Weitere Informationen

Die Skriptausführung wurde gestoppt, weil irgendetwas nicht korrekt funktioniert. Die eigentliche Fehlermeldung wird aus Sicherheitsgründen hinter dieser Meldung verborgen und findet sich in der aktuellen Log-Datei (siehe oben). Wenn Sie die Fehlermeldung nicht verstehen oder nicht wissen, wie das Problem zu beheben ist, durchsuchen Sie die Contao-FAQs oder besuchen Sie die Contao-Supportseite.