Tcpdf – Variable Height Table Rows With MultiCell

This post as been superseded. Please see my new post on the subject.

During my use of the excellent tcpdf library for creating pdf documents with php, I came across an interesting problem when creating a pdf featuring a grid of data. Although I could have use an html grid to present the data, I was trying to avoid the use of html and keep to the Cell(), MultiCell(), Text() etc. methods to render the document.

The content of some of the cells in this particular grid were quite long and so some wrapping of text would (and needed to) occur. The MultiCell method handles this and will wrap the text, expanding accordingly. Now I was trying to make a grid row, so needed all of the cells to be the same height – and there lay the problem – I did not know how high to make the other cells. It was a chicken and egg situation: I needed to know the height of the cell before drawing them but did not know how high they needed to be until after I had drawn them.

I studied the documentation hard but realised that the answer was not to try and generate the cells, borders and all, in one pass. I could achieve what I needed by drawing each row twice – once for the content and once for the borders.

The MultiCell function kindly returns the height that the cell was drawn, so by remembering the maximum value it was when drawing a row of cells, I could then go back and draw the borders to that maximum height:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
foreach($data as $row) {
	$maxnocells = 0;
	$cellcount = 0;
	//write text first
	$startX = $pdf->GetX();
	$startY = $pdf->GetY();
	//draw cells and record maximum cellcount
	//cell height is 6 and width is 80
	$cellcount = $pdf->MultiCell(80,6,$row['cell1data'],0,'L',0,0);
	if ($cellcount > $maxnocells ) {$maxnocells = $cellcount;}
	$cellcount = $pdf->MultiCell(80,6,$row['cell2data'],0,'L',0,0);
	if ($cellcount > $maxnocells ) {$maxnocells = $cellcount;}
	$cellcount = $pdf->MultiCell(80,6,$row['cell3data'],0,'L',0,0);
	if ($cellcount > $maxnocells ) {$maxnocells = $cellcount;}
	$pdf->SetXY($startX,$startY);
 
	//now do borders and fill
	//cell height is 6 times the max number of cells
	$pdf->MultiCell(80,$maxnocells * 6,'','LR','L',0,0);
	$pdf->MultiCell(80,$maxnocells * 6,'','LR','L',0,0);
	$pdf->MultiCell(80,$maxnocells * 6,'','LR','L',0,0);
 
	$pdf->Ln();
}

Note that the last parameter I set in MultiCell is set to 0 which means that no new line occurs once a cell is drawn. This means that the cells will appear side-by-side and also means that I need to manually create the new line when I finish drawing the row.

10 Responses to “Tcpdf – Variable Height Table Rows With MultiCell”

  1. mike  on March 26th, 2009

    Any idea how to do this when a multicell’s content is so large that the cell spans pages? In this case, the value returned by multicell seems to be erroneous, and since the position is now on the last page, only the last page gets borders.

    I appreciate any pointers.

  2. admin  on March 26th, 2009

    Wow, yes that is an issue with this method. A quick and dirty answer would be to utilise the max height ($maxh) parameter of multicell. That is a bit brutal however and is not a proper solution. I will have a look at this over the weekend and see what I can come up with, I suspect it affects my implementation too..

  3. mike  on March 27th, 2009

    I appreciate your help.

    It seems that there must be a way to maybe extend the class and rewrite the MultiCell function so that borders get painted on every screen. I am trying to create a single/multi-page invoice, and having the borders painted only on some pages is not acceptable.

  4. jmmontero  on March 27th, 2009

    Excellent and Smart solution!! I took your approach and it worked for me!.

    By the way, if you don’t mind I would like to ask you, How can I print the same headers on each page using TCPDF? Your answer will be greatly appreciated.

  5. mike  on March 27th, 2009

    In response to jmmontero,

    “How can I print the same headers on each page using TCPDF?”

    Simply define the header parameters:
    $pdf->SetHeaderData(PDF_HEADER_LOGO, PDF_HEADER_LOGO_WIDTH, PDF_HEADER_TITLE, PDF_HEADER_STRING);

    Set the font:
    $pdf->setHeaderFont(Array(PDF_FONT_NAME_MAIN, ”, PDF_FONT_SIZE_MAIN));

    Set the margin:
    $pdf->SetHeaderMargin(PDF_MARGIN_HEADER);

    Then call AddPage() and add your page data.

  6. admin  on March 27th, 2009

    mike and jmmontero , please see my new post on the subject. Hopefully it will work for you.

  7. fm  on May 6th, 2009

    there is an error, when text data are printed at end of page, frames are printed at next page. you need to put

    if ($pdf->GetPage()!=$startPage) $pdf->SetPage($startPage);
    before
    $pdf->SetXY($startX,$startY);

    and

    $startPage=$pdf->GetPage();
    after
    $startY = $pdf->GetY();

  8. dan  on May 6th, 2009

    @fm – This article has been superseded by my newer article, as I realised there were some flaws in this one. Have a read of that one and you will see I have taken into account page breaks in a more comprehensive manner.

  9. puppyohaire  on November 26th, 2009

    thanks man i help i lot, though i do some modification so that i will display the output that i need… thanks again


Trackbacks/Pingbacks

  1. [...] the original: Tcpdf – Variable Height Table Rows With MultiCell Related ArticlesBookmarksTags PHP Development Tools – Keeping it Simple and Mostly Fre If [...]

Leave a Reply