Skip to content

Instantly share code, notes, and snippets.

@johnballantyne
Created November 16, 2012 18:22
Show Gist options
  • Save johnballantyne/4089627 to your computer and use it in GitHub Desktop.
Save johnballantyne/4089627 to your computer and use it in GitHub Desktop.
GetMultiCellHeight() script for FPDF
function GetMultiCellHeight($w, $h, $txt, $border=null, $align='J') {
// Calculate MultiCell with automatic or explicit line breaks height
// $border is un-used, but I kept it in the parameters to keep the call
// to this function consistent with 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("\r",'',$txt);
$nb = strlen($s);
if($nb>0 && $s[$nb-1]=="\n")
$nb--;
$sep = -1;
$i = 0;
$j = 0;
$l = 0;
$ns = 0;
$height = 0;
while($i<$nb)
{
// Get next character
$c = $s[$i];
if($c=="\n")
{
// Explicit line break
if($this->ws>0)
{
$this->ws = 0;
$this->_out('0 Tw');
}
//Increase Height
$height += $h;
$i++;
$sep = -1;
$j = $i;
$l = 0;
$ns = 0;
continue;
}
if($c==' ')
{
$sep = $i;
$ls = $l;
$ns++;
}
$l += $cw[$c];
if($l>$wmax)
{
// Automatic line break
if($sep==-1)
{
if($i==$j)
$i++;
if($this->ws>0)
{
$this->ws = 0;
$this->_out('0 Tw');
}
//Increase Height
$height += $h;
}
else
{
if($align=='J')
{
$this->ws = ($ns>1) ? ($wmax-$ls)/1000*$this->FontSize/($ns-1) : 0;
$this->_out(sprintf('%.3F Tw',$this->ws*$this->k));
}
//Increase Height
$height += $h;
$i = $sep+1;
}
$sep = -1;
$j = $i;
$l = 0;
$ns = 0;
}
else
$i++;
}
// Last chunk
if($this->ws>0)
{
$this->ws = 0;
$this->_out('0 Tw');
}
//Increase Height
$height += $h;
return $height;
}
@dravek
Copy link

dravek commented Mar 19, 2016

Thanks so much!!

@phpdave
Copy link

phpdave commented Feb 13, 2017

Thank you sir! Just found this!

@shklyarik
Copy link

On php 7.1 I had the error "Warning: Illegal string offset 'E'"
in this place
$l += $cw[$c];

@Assem
Copy link

Assem commented May 27, 2017

Thks

@OMA2k
Copy link

OMA2k commented Jul 17, 2017

Thanks for the script, but I'm having the same problem as "shklyarik". Sadly, since most variables have cryptic single letter names, it's hard to understand the code and fix the problem. If I just check for the existence of $cw[$c] with isset() to avoid the warnings, then the result is it doesn't calculate the height correctly anyway (all MultiCells are reported as single line height).

@DenoBY
Copy link

DenoBY commented Jun 5, 2019

I had problems calculating if I use big text. I managed to solve it by removing the line $cw = &$this->CurrentFont['cw'];

@dock21
Copy link

dock21 commented Jan 5, 2021

I know this may be old but as I used this method, I had an issue on number of chars too. I resolved it by using mb_strlen instead of strlen. It woks prefectly now. Hop this helps and many thanks for the script.

@ericmulovhedzi
Copy link

Genius, genius, genius script..

@Clickedu-fchavez
Copy link

Thank you so much, I've been looking to solve a bug almost 2 weeks and this is the function I needed. Really appreciate it

@emkowale
Copy link

I really want to try this, but I can't get it to work. Do I put the function is a class like this?:

class PDF extends FPDF {
function GetMultiCellHeight($w,$h,$txt,$border,$align){
...
}
}

and call it like this?:

$multiCellHeight=$pdf->GetMultiCellHeight(4,.2,$description,0,'L');

Thanks,
Eric

@oueddadidou
Copy link

voici ma methode, c'est du bidouille, mais elle marche bien
`$w = array(8,60, 15, 25,25); // A5
for($i=0;$i<count($header);$i++)
$this->Cell($w[$i],7,$header[$i],1,0,'C',true);
$this->Ln();
// Restauration des couleurs et de la police
$this->SetFillColor(224,235,255);
$this->SetTextColor(0);
// $this->SetFont('');
// Données
$fill = false;

$tableSize = sizeof($data);
$solde = 0;
$l = 1;
for($i = 0 ; $i<$tableSize; $i ++){
	$solde += intval($data[$i]['montant']);
    $posXX0 = $this->getX();
    $this->Cell($w[0],6,'','LRT',0,'C',$fill);
    $posX0 = $this->getX();
    $posY0 = $this->getY();
    $this->MultiCell($w[1],6,$data[$i]['article'],'LRT',0,'C');
    $posY1 = $this->getY();
    $h=   $posY1 - $posY0;
    
    $this->SetXY($posX0 + $w[1], $posY0);
    $this->Cell($w[2], $h,$data[$i]['quantite'],'LRT',0,'C',$fill);
    $this->Cell($w[3], $h,number_format($data[$i]['prix_vente'], 0, '.', ' '),'LRT',0,'C',$fill);
    $this->Cell($w[4], $h,number_format($data[$i]['montant'], 0, '.', ' '),'LRT',0,'C',$fill);
    $this->SetXY($posXX0, $posY0);
    
    $this->Cell($w[0],$h,$l,'LR',0,'C',$fill);
   // $this->Cell(array_sum($w), 0, '', 'T');
    $this->Ln();
    // $fill = !$fill;
    $l += 1;
}`

@ucros
Copy link

ucros commented Jun 19, 2023

Thank you very much, it worked for me, although it served me more as a line break counter or the number of lines that a text could have based on the cell width, just by making this change $height++; so that it only counts the lines.
Alternatively, you can change $height to $lines to avoid confusion. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment