This article aims to help those who like myself wondered how to make text wrap within a table cell using FPDF to generate a the PDF. A few posts around the web seem to have missed the point that wrapping comes out of the box in FPDF using the MultiCell function. However, it’s just a tiny bit tricky but not prohibitively so. So, this is what we are aiming for – an invoice.

There are 2 examples of wrapping here. Firstly the client address is wrapped, and secondly the first row of the line item data has a wrapped description.
In both cases the MultiCell in-built function is used. Before I had this solution working I was using the Cell function. In that case, long text simply continued through to the next cell ‘Quantity’. In the case of Cell, you can simply output a series of calls to the function with a cell width and so fourth and the cells will line up against each other on the same line.
When I switched to MultiCell for the first cell of each row only, I found that it would cause all subsequent cells in the same row to wrap to the next line. Therefore my solution was to use the SetXY function to reposition the ‘cursor’ back to where the 2nd cell of the current row would normally be, and then proceed to use Cell calls.
In order to do that it’s a case of marking the current X and Y coordinates of the cursor prior to entering the line item loop and calling SetXY just after the 1st cell MultiCell function call. That solved the line wrapping issue and my text wrapped inside the first cell – great.
The second issue however is that the MultiCell is arbitrarily high depending on the amount of text wrapping going on. I had been provided a static height to my Cell calls as as such they were now out of line with the first column, that is, the text and border lines were all out of sync with the 1st column.
To solve that problem it was a case of grabbing the Y coordinate of the cursor before and immediately after the MultiCell call, finding the difference to ascertain the height of the cell, and then using this to size the height of the remaining Cell calls on the row.
Source Code
Please feel free to download the source code for this article which builds the invoice PDF as described.
The source code is provided as a ZIP file with index.php and InvoicePDF.class.php. You will need to obtain the FPDF library yourself and modify the index.php include file locations.
Best of luck!

Hi
Your article is very needful. I would like wrap the text in a table. But it it not known that which is wrapped. And the remaining cells are not drawn with the same height of the wrapped cell. If you don’t mind can you give a solution for this. I need it urgently. In this site the code is not available. Pl. do the needful for me
Comment by prasannak — March 25, 2008 @ 6:55 am
Great article… and this very useful for me. thanx
Comment by xenop4ti — May 29, 2009 @ 9:04 am
Hi.
Your post was “illuminating” to me. I had the same problem and I could solve it thanks to this. However, my solution was a little modification of yours. That was because my column which needed MultiCell was the 3rd, not the first. So, I needed the height previous to start adding cells. To achieve this:
1) Before starting each row, get the height of the MultiCell. How?
a) Save the current X and Y positions.
b) use SetX(-10000) to get the cursor totally out of sight
c) draw the MultiCell with its content and row height (will be hidden)
d) get a height factor (2 for twice row_height, 3 for thrice, etc.)
e) reset your cursor with the saved positions
2) Start writing your Cells and MultiCells. Beware when writing row_heights:
a) Cell height: row_height * row_height_factor (6*2=12)
b) MultiCell height: row_height (6 becomes 12… on wordwrap)
* Remembering the basics: after MultiCell, reposition the cursor to the right.
Any comments or q’s, you can email me alejandroleone@gmail.com
Thanx for the post
Comment by Zeth — June 9, 2009 @ 9:35 pm
Great post. Thanks for this. Exactly what I was looking for. You would think that FPDF would build this into the cell function automatically somehow or address this issue better. But it is free
Thanks again.
Josh
Comment by Josh P — June 12, 2009 @ 9:46 pm
You saved me lot of work my friend. appreciated this article from core of my heart. keep up the good work
Comment by jas — June 19, 2009 @ 5:01 am
This code is good. Thanks for this. But This will work if there is only one page. If you have successive pages, the column length of the first row of new page will be more and thus affecting the design.
Comment by Muthu Vijayan — July 8, 2009 @ 12:22 pm
I worked around the issue and created a quick patch for this. The point is that we should reset the value of yH when a new page occurs. so here is the code.
$set = 0;
foreach($data as $row)
{
$y1 = $this->GetY();
$this->MultiCell($w[0], 6, $row[0], ‘LRB’);
$y2 = $this->GetY();
$yH = $y2 – $y1;
// if it is a new page, reset the y axis value, (This will work only for two pages)
if($this->pageNo() == 2 && !$set)
{
$yH= 6;
$set = 1; //set this so that this will apply the value only for the first record.
}
$this->SetXY($x + $w[0], $this->GetY() – $yH);
Please not this will work only for two pages, if you want more catch the current page and before the loop and check it with the current page. if($this->pageNo() != $oldPageNo)
Hope this helps someone!!
Comment by Muthu Vijayan — July 9, 2009 @ 8:57 am
Exactly what I was looking for! I spent ages trying to work this out!
Comment by Ed — August 3, 2009 @ 10:50 pm
Great! I was looking for this but with little modifications…how can i pull data from mysql and put them in an invoice.
E.g I want to change these lines:
$data = array();
$data[] = array($textWrap, 1, 50, 50, 0, 50);
$data[] = array($textNoWrap, 1, 10500, 10500, 0, 10500);
Please assist.
Comment by harry — September 4, 2009 @ 10:27 am
Hm. Just starting to look at this now for something I am working on. What if we need to draw many MultiCells or maybe the subsequent column requires a MultiCell? Do we have to go back and recalculate the previous cell(s) and compensate for the new height? Is this possible?
Comment by Keith — September 8, 2009 @ 6:12 pm
Hi,
This was a very useful one throwing light on fpdf wordwrap functionality which otherwise would have been a hard nut. It would be little more helpful if you could expand the worwrap to other columns of a table.
Here only the first column of a table is mentioned but, if wordwrap is to be applied on other columns then your comment on this will be musch appreciated for newbies like me.
Thanking you in advance.
Comment by kapil — November 26, 2009 @ 11:42 am
Hi, can you put a example with this sentence if($this->pageNo() != $oldPageNo), for more than two pages please !!
best regards !!
Comment by luigui — December 4, 2009 @ 7:20 am
Amazing tip! You save a lot of time.
Comment by Bigaidas — December 9, 2009 @ 2:10 pm
Hi the above code was very useful. But I found a bug I don’t know what causes it. If the table reaches the second page the cells are scattered.Try to increase the loop for number of rows.
Comment by ian — February 5, 2010 @ 8:05 am
Thanks very much. This helped out a lot!
Comment by Ben — February 18, 2010 @ 9:06 pm
Thanks…….
The Code is very help full……….
Comment by Shamnas K s — March 20, 2010 @ 6:56 am
You are the man, you saved me a lot of time.
I really appreciate your efforts, stay blessed
Comment by Moses — May 3, 2010 @ 6:34 am
Very helpful for me!!! Thanx!!
Comment by nuzil — June 8, 2010 @ 8:13 am