PHP free pdf

Translations: "Română" |

Share on:

Now some time a go, a got a task to create a form of presentation of a products list. It wasn’t supposed to be a catalog, it was supposed to be a simple products list. The client let me decide between xls and pdf. I choose pdf, but the problem was what to use. For the sake of portability I decided not to use the php_pdflib module, so no problems will arise  if I try to reuse the application on another project.

But Google as usual gave me the solution: fpdf! Fpdf is a module independent php class, created with php4. I must admit that it took me several hours until I got to finish the file, but I’m happy with the results, and even though it took a little more than initially estimated, once I got the picture, everything went well.

Basically about everything needed is in the manual.

Very happy with the result I wanted to go to step 2, the invoice in pdf format.

As in HTML, I was used when the information is in a table format, to format it as such, but in fpdf there are no actual tables, there are only cells separated by a new row. And another problem is related to table format, cells do not re size dynamically by there content like in html.

The first problem is easy to solve, you just simply call the Ln() method when you want to go to a new row, but because the cells are not actually cells they may cross each other fairly easily using the cell width:

 1require('fpdf.php');
 2
 3// create a class instance
 4$pdf=new FPDF();
 5
 6// setting a font
 7$pdf->SetFont('Arial','',5);
 8
 9// add a new page
10$pdf->AddPage();
11
12// first two cells, first couple of parameters are the width and the height
13$pdf->Cell(20, 10, "celula 1", 1, 0, "C");
14$pdf->Cell(20, 10, "celula 2", 1, 0, "C");
15
16// a new row to go to the next line
17$pdf->Ln();
18
19// the third cell with the width of the first 2 cells, the equivalent of
20// "rowspan" from html
21$pdf->Cell(40, 10, "celula 3", 1, 0, "C");
22
23// display the result
24$pdf->Output();

The result looks something like this:

tabel simplu cu fpdf

So far everything seems ok, I looked full of confidence upon the next step in the invoice, displaying the invoice fields. Here a problem arisen, fields do not resize and they look at least bizarre. For instance, two cells look like this:

1$pdf->Cell(20, 10, "Lorem ipsum dolor sit amet", 1, 0, "L");
2$pdf->Cell(20, 10, "celula 2", 1, 0, "C");

The result:

And in that moment my world has fallen in my head, especially that I remembered of a bill received in the mail with the same problem. The solution is not very difficult, but it took me quite a lot of digging: beside the Cell() method, there is a method called MultiCell(), which is able to resize in an almost elegant way. The thing is that the two elements have to be combined in fpdf to generate an invoice table:

 1// first cell width
 2$w1 = 20;
 3
 4// second cell width
 5$w2 = 20;
 6
 7// find the cursor position and store it
 8$y1 = $pdf->GetY();
 9$x1 = $pdf->GetX();
10
11// the "multiCell" cell, which will resize automaticly
12$pdf->MultiCell($w1, 10, "Lorem ipsum dolor sit amet", 1, "L"); 
13
14// find the cursor position after the first cell was displayed
15$y2 = $pdf->GetY();
16
17// find the height of the first cell
18$hCell = $y2 - $y1;
19
20// set the cursor position to the new location
21$pdf->SetXY($x1+$w1, $pdf->GetY() - $hCell);
22
23// display the second cell
24$pdf->Cell($w2, $hCell, "celula 2", 1, 0, "C");

And the result is:

Here the smile was reappearing. The last step is positioning the first cell, the cell with the product number sequence in front of the two cells. In the example below the width of the cell was reduced by 1. Basically you have to move the cursor to the right, by the width of the first cell, to display the cell with will be widthed and to calculate its height. After we calculated the height of the resized cell, we can reposition the cursor to the initial position and display the first cell with the new height. After that we move the cursor after the second cell and we continue with the rest of the cells. Example:

 1// width of the firs cell
 2$w1 = 10;
 3
 4// width of the second cell
 5$w2 = 20;
 6
 7// width of the third cell
 8$w3 = 20;
 9
10// find the cursor's position and store it
11$y1 = $pdf->GetY();
12$x1 = $pdf->GetX();
13
14$pdf->SetXY($x1+$w1, $pdf->GetY());
15
16// the "multiCell" cell, which will resize automaticly
17$pdf->MultiCell($w2, 10, "Lorem ipsum dolor sit amet", 1, "L"); 
18
19// find the cursor position after the second cell was displayed
20$y2 = $pdf->GetY();
21
22// find the height of the multiCell
23$hCell = $y2 - $y1;
24
25// setting the cursor to the initial coordonates to display the first cell
26$pdf->SetXY($x1, $y1);
27
28// display the first cell
29$pdf->Cell($w1, $hCell, "celula 1", 1, 0, "C");
30
31// setting cursor to the new calculated location
32$pdf->SetXY($x1+$w1+$w2, $y1);
33
34// display the third cell
35$pdf->Cell($w3, $hCell, "celula 3", 1, 0, "C");
36
37// a new row to go to the next line.
38$pdf->Ln();

The result is:

And the problem was solved. From here is just a problem of multiplying the row according to the number of products on the invoice. If your using fpdf don’t forget to check the manual, is very simple and concise.