Create PDF documents Online with TCPDF
Many web applications output documents like invoices, contracts or just web pages in the PDF format. There are a few PHP classes which can be used for creating PDF files online, one of them is TCPDF. This tutorial is about how-to use the TCPDF class while creating a simple invoice document. A function that creates invoices online, is very common for a website that sells goods or services.
Why TCPDF and not some other PHP class?
TCPDF is based on the FPDF class, a very stable project written originally for PHP4. Since several years has TCPDF much more features than FPDF and is written for PHP5. The TCPDF has also some great documentation and of course examples for all important PDF jobs like:
WriteHTML and RTL support, Multiple columns, JavaScript and Forms, Bookmarks (Table of Content), Multicell complex alignment, Barcodes, Set PDF viewer display preferences, EPS/AI vectorial images and many more.
The Zend Framework has some PDF class too…
Yes right, the first plan was to write this tutorial about the Zend Framework, but after writing a few rows of code I’ve noticed that the PDF Class is missing some important functions, like the MultiCell, which is used to wrap multiple rows of text. It’s a required function which was suggested as the Zend_Pdf_Cell 2 years ago and didn’t find the way to the core version until now. I like the Zend Framework a lot but not for creating PDF documents, the PDF class is much too limited. :(
Okay let’s start the tutorial:
In this tutorial we create a PDF invoice including header logo, the invoice rows, an information box and some footer row.
In our code we include some PHP files, next we’ve created a small class extension to have a custom header/footer and some handy method which creates a text box.
require_once('tcpdf/config/lang/eng.php');
require_once('tcpdf/tcpdf.php');
class MYPDF extends TCPDF {
public function Header() {
$this->setJPEGQuality(90);
$this->Image('logo.png', 120, 10, 75, 0, 'PNG', 'https://www.finalwebsites.com');
}
public function Footer() {
$this->SetY(-15);
$this->SetFont(PDF_FONT_NAME_MAIN, 'I', 8);
$this->Cell(0, 10, 'finalwebsites.com - PHP Script Resource, PHP classes and code for web developer', 0, false, 'C');
}
public function CreateTextBox($textval, $x = 0, $y, $width = 0, $height = 10, $fontsize = 10, $fontstyle = '', $align = 'L') {
$this->SetXY($x+20, $y); // 20 = margin left
$this->SetFont(PDF_FONT_NAME_MAIN, $fontstyle, $fontsize);
$this->Cell($width, $height, $textval, 0, false, $align);
}
}
The header method has only two functions, one sets the image quality and the second will place an image (including hyperlink) on a defined place (x=120, Y=10, width=75). All coordinates are measured in Millimeters and the height for the image is calculated by the script. Inside the footer method we’re using some basic TCPDF methods to define the position, the font/style and the cell with the footer text. The third method (CreateTextBox) is just a group of TCPDF functions which makes it easier to place some text box into the PDF document. Note, the constant variable PDF_FONT_NAME_MAIN is defined inside the TCPDF config file, which is located inside the config directory.
The invoice header
The following code will create a TCPDF object with default values, the PDF meta data gets defined (author, title, etc.), a page is added and the invoice header with information is created using our custom text box method.
// create a PDF object
$pdf = new MYPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
// set document (meta) information
$pdf->SetCreator(PDF_CREATOR);
$pdf->SetAuthor('Olaf Lederer');
$pdf->SetTitle('TCPDF Example');
$pdf->SetSubject('TCPDF Tutorial');
$pdf->SetKeywords('TCPDF, PDF, example, tutorial');
// add a page
$pdf->AddPage();
// create address box
$pdf->CreateTextBox('Customer name Inc.', 0, 55, 80, 10, 10, 'B');
$pdf->CreateTextBox('Mr. Tom Cat', 0, 60, 80, 10, 10);
$pdf->CreateTextBox('Street address', 0, 65, 80, 10, 10);
$pdf->CreateTextBox('Zip, city name', 0, 70, 80, 10, 10);
// invoice title / number
$pdf->CreateTextBox('Invoice #201012345', 0, 90, 120, 20, 16);
// date, order ref
$pdf->CreateTextBox('Date: '.date('Y-m-d'), 0, 100, 0, 10, 10, '', 'R');
$pdf->CreateTextBox('Order ref.: #6765765', 0, 105, 0, 10, 10, '', 'R');
Invoice Rows
Now we create the information about the products we like put into the PDF invoice. First we create some headers and than we use a foreach loop to output our $orders array.
// list headers
$pdf->CreateTextBox('Quantity', 0, 120, 20, 10, 10, 'B', 'C');
$pdf->CreateTextBox('Product or service', 20, 120, 90, 10, 10, 'B');
$pdf->CreateTextBox('Price', 110, 120, 30, 10, 10, 'B', 'R');
$pdf->CreateTextBox('Amount', 140, 120, 30, 10, 10, 'B', 'R');
$pdf->Line(20, 129, 195, 129);
// some example data
$orders[] = array('quant' => 5, 'descr' => '.com domain registration', 'price' => 9.95);
$orders[] = array('quant' => 3, 'descr' => '.net domain name renewal', 'price' => 11.95);
$orders[] = array('quant' => 1, 'descr' => 'SSL certificate 256-Byte encryption', 'price' => 99.95);
$orders[] = array('quant' => 1, 'descr' => '25GB VPS Hosting, 200GB Bandwidth', 'price' => 19.95);
$currY = 128;
$total = 0;
foreach ($orders as $row) {
$pdf->CreateTextBox($row['quant'], 0, $currY, 20, 10, 10, '', 'C');
$pdf->CreateTextBox($row['descr'], 20, $currY, 90, 10, 10, '');
$pdf->CreateTextBox('$'.$row['price'], 110, $currY, 30, 10, 10, '', 'R');
$amount = $row['quant']*$row['price'];
$pdf->CreateTextBox('$'.$amount, 140, $currY, 30, 10, 10, '', 'R');
$currY = $currY+5;
$total = $total+$amount;
}
$pdf->Line(20, $currY+4, 195, $currY+4);
After the headers and after the list of invoice items we create a line. Inside the loop, we use the variable $currY to raise the Y coordinate by 5 for each new row. The row amount is calculated by PHP and also the total amount is raised inside the foreach loop.
Invoice footer and information
First we create a total row using the value from the variable $total we created before. After that row we have a MultiCell which can hold the payment conditions or just some other information. You can use HTML code in this cell as well, for example a link to your terms and conditions.
// output the total row
$pdf->CreateTextBox('Total', 20, $currY+5, 135, 10, 10, 'B', 'R');
$pdf->CreateTextBox('$'.number_format($total, 2, '.', ''), 140, $currY+5, 30, 10, 10, 'B', 'R');
// some payment instructions or information
$pdf->setXY(20, $currY+30);
$pdf->SetFont(PDF_FONT_NAME_MAIN, '', 10);
$pdf->MultiCell(175, 10, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Vestibulum sagittis venenatis urna, in pellentesque ipsum pulvinar eu. In nec nulla libero, eu sagittis diam. Aenean egestas pharetra urna, et tristique metus egestas nec. Aliquam erat volutpat. Fusce pretium dapibus tellus.', 0, 'L', 0, 1, '', '', true, null, true);
//Close and output PDF document
$pdf->Output('test.pdf', 'F');
At the end we call the output method which will safe the created PDF under the name test.pdf and sends the document to the browser.
This is just an example to show how easy it is to create PDF files online. Before you start your own PDF scripts, check all the TCPDF examples to get an idea how-to use the different methods.
Published in: PHP Scripts
You should use mpdf, it translate straight html to pdf.
A must have
Hello Q,
at the moment that I’m creating an invoice using the submitted data, there is no html available.
If I have an existing html page and I need a PDF version I will use tools like mdf
I have to 2nd the recommendation for mPDF. We use it extensively, and the integration with mPDFi for template handling is superb. I can create a PDF document and use it as the base for any form, and then just put the dynamic content ontop of the template. THe HTML support is incredible, and its perfect for any business form that you have to generate in PHP as a PDF document.
Hi,
yep I used mPDF some time ago to fill an existing pdf form with form data, great and easy if you have an existing PDF file.
If you start from the scratch without anything you should consider the TCPDF class ;)
Maybe I missed somthing, if mPDF has a feature to create a dynamic pdf from the scratch please show me the source.
Thanks.
Hi again,
We used SAP for printing and it was hard to do and maintain, we switched about 4 documents to mpdf in 2 weeks.
If you want to see an invoice sample using mdpf please go there : http://mpdf1.com/manual/index.php?tid=366&searchstring=invoice
To add more to my point, mpdf documentation is one of the best I’ve seen and Ian N Back is really dedicated to the project. Hes been fixing really quickly every issue I found. One of the best Open source project around.
Cheers,
Q
And don’t get me wrong, TCPDF is a really good tool too.
Q
I think both project are good for differnet purposes. If you have already a document (PDF/HTML) use mPDF, if you have “nothing” use TCPDF. This because it makes no sense to create HTML code first to convert the same code afterwards to PDF.
Maybe but if you think about maintenance and debug, an HTML document is really easy to debug & create with a notepad and Firefox+firebug.
And if you need to hire consultant, looking for someone who knows HTML is a lot easier to find than TCPDF.
cheers,
Sure it’s easier to create HTML code but in most applications you need to write PHP code to get the HTML ;)
Q, I used FPDF for years because it’s fast, compact and less server load intensive. Because of some limitations I moved over to TCPDF. Actually one of the weakest points is the file size from the class: 768KB, this is a lot for a busy website. Just checked the mPDF class: 1.1mb and the code is not written for PHP5.
I would be happy if the Zend_PDF class has more features…
File size is linked to encoding, if you don’t need to use UNICODE for your document, then it will be a lot smaller.
the invoice sample, is only weight 8kb…
I’m talking about the class file that is 1.1mb, your web server needs to load this file into the memory first before your custom script is executed.
We created a restfull service on a php server that receive HTML from other enterprise application and change it to PDF.
true about the size, you need a big server to handle it
lol the fpdf class file is less than 40KB
The above posts about mPDF seems from the same user trying to promote it ;)
I’m an happy user of TCPDF and from my point of view TCPDF and mPDF are uncomparable because the latter contains a lot of code borrowed from TCPDF and different license (LGPL vs GPL). Additionally TCPDF includes tons of killer features that are missing in mPDF (i.e: bidirectional-algorithm for RTL languages, digital signature, document encryption, pre-press utilities, native SVG support, and much more).
AFAIK, the latest TCPDF release is able to convert HTML much better than mPDF (at least for my purposes) and includes support for CSS files.
I do not understand why the mPDF author started a new project borrowing a lot of code from TCPDF instead of collaborating with the original author.
Thanks Erika ;)
Any idea on how to go with inserting variables into an pdf eg. form submited date and then attaching that pdf to an email?
Thanks in advance :)
Hi clinton,
do you need a form function in your PDF or do you pass form data to your pdf script?
Can I attach files to the pdf document with TCPDF? I think it’s called annotations. For example some XML file containing the invoice data in structured form or images or anything binary. Thanks!
Yes, annotations are supported (check the examples page on TCPDF page)
You need to use a snippet like:
Hi Olaf
Im passing form submited data to a pdf script, as soon as the form is submited the pdf doc is created with hes submited variables in there.
I thought somthing like name; ?> could work, i just have no idea how i am going to attach this created pdf to the email thats sent to the user.
Thanks Again
Clinton
sorry that didnt come out corectly.
echo $post->email; should be able to post the data into a pdf if im not mistaken.
Hi clinton,
check the demo link I posted in the begin, I’m using on that page the code from here together with the form.
Instead of the static values you can use the $_POST vars like:
Compare this code snippet with the equivalent code used in this tutorial.
Why not just use the Adobe products?
Hi Joe,
maybe because adobe is not an online product?
or because adobe software is expensive ;)
Thanks Olaf!
Hi
Olaf thanks for help but it seems im geting an error “Call to undefined method TCPDF::CreateTextBox()” , im also not finding any documentation on posting form data.
Any Ideas?
Thanks
Clinton
Hi,
the method CreateTextBox() is part of the tutorial. What do you mean with documentation about posting data?
Do you know how to submit and process data using a form and PHP?
Hi,
Yes i can post data in emails fine but posting the data in a pdf is deferent, it seems tcpdf is not recognizing the CreateTextBox() method.
Thanks Again.
Do you used the code the same way as I did?
You need to create the class extension first to get the method into the objects scope. Than start creating an object from that class extension.
Posting a form to some pdf script works the same as for the email scripts.
This is a nice class.
Is there a solution when you have to many rows between your header and footer so you get a new page with the endresult and some rows ?
Yes it’s possible, check this example (no. 48 # Table header and row span)
OK, that is nice to know, but how will this be done with as many rows that fit between the header and the footer ?
Is this some sort of big if-statement ?
yes right you need to count the rows.
if the count exceeds some number you use the addpage method. Maybe something like:
$count = 0;
$perPage = 5;
while ($rows = mysql_fetch_object($result)) {
// show the rows here
if ($count % $perPage == 0) $pdf->AddPage();
$count++;
}
(the code is just an example is not tested for good)
OK, so it’s not possible to “discover” it on page-size ?
I remember a auto-pagebreak function in FPDF and I’m sure this function is available in TCPDF as well.
Do you check the manual for such method?
It might look cleaner to create a page break based on the number of rows instead.
Yes I have seen the same on FPDF, but also on page size.
I need to check some old FPDF based script that I have somewhere and how it worked.
Keep you posted !
Thank you very much. This helps a lot.
Now that I’ve spend some time trying to learn txpdf, is there any docs on text formatting other than the examples?
I’ve got big invoice-like files with like 30,000 invoices per file, I’m converting each invoice-like statement to PDF using tcpdf. How do I get a line of text to space evenly? There are no tabs; just space seperating some of the text.
hello John,
A PDF is different from a word doc, all text or images is bounded in a box, this box is placed my an x/y coordinate. If you need to place stuff in some kind of tab format you should don this using php.
I did the same for the order rows (using a custom function/method)
hi all,
working with annotations, how can i attach file to pdf without placing any annotaion in the content area? with the tcpdf example a pin shows up linking to the file. i don´t want to have any icon in the textarea, just the files attached to the pdf.
can naybody help?
Hello,
Nice tutorial. But currY is in some places replaced by currX.
I like currY more :)
Hello,
I discovered that this tutorial only works when it is al displayable on one page. When there are to many orders in the array the data is display on top of the company logo on the second page. Is it possible to show the logo only on the first page?
Also the orders that don’t fit on the first page. Are completely stretched on multiple pages (every array item is display on it’s own page.
Hi Arthur,
Thanks for pointing me on the currY-bug (it’s fixed)
A tutorial including multi page function would be too long.
What you need to to is count your rows (the dynamic part) and pass a pagebreak to the script. There is also a automatic pagebreak (check the TSPDF manual) but I never used it. I tried the automatic pagebreak with FPDF and that was pretty ugly.
Hi,
I ran your example – it looks lovely, but when I save the pdf file it comes out as 3.8 MB! Don’t know why it is so large (especially since to save it as a BLOB it’s less than 10 kB). Is there any way to make this smaller? I just did a complete copy and paste into a test file, just removing the image at current, so should be exactly what you have. Thanks!
Hello Stephanie, what kind of data to you use? Do you use an existing PDF as base document?
I am new to tcpdf and I was wondering if it was possible to read in an existing pdf document and then merge it with data that I create using tcpdf? If anyone has done this and has a simple example I would be very grateful
Hi Olaf,
I put all of your above code together to create a PHP file and try to understand and use these nice codes, but it does not work properly. Please check the codes as follows, are there anything missing? So sorry and please ignore my previous post.
Hi Fa,
do you get any error message? What happens instead?
I just spent a long time trying to figure out why this script was timing out after 4 minutes.
The constructor in the example uses the constant PDF_UNIT, as defined in the original tcpdf_config.php file, as ‘mm’.
However, I had revised the tcpdf_config.php file, setting
PDF_UNIT = ‘in’.
As a result, the server stalled on trying to scale my Image in the MYPDF::Header() method to 30 inches wide instead of 30 mm wide.
Upon changing the constructor call to use “mm” as the PDF_UNIT, the script generated a PDF very quickly.
Hi RJ,
thanks for sharing this information. Most PDF classes I know using mm for postions and dimensions in side the code. I guess the inches are only for the output paper format.
Hi, I’m using tcpdf for a web application however I have 3 applications running off of one domain/hosting. Will the pdf script work with just one set of the files in the root or is there another way to go about this?
Hi, thats strange maybe some coding error? If you provider disabled error reporting you get only a white screen :(
Hi Olaf,
I’m trying to create a similar form to pdf generator as shown in the demo you posted. I’m relatively new at PHP, and i was wondering how you made the connection between the html form and the post variables in the tcpdf code. Can you help me with that?
Thanks in advance.
Nevermind, was missing the CreateTextBox method. Works like a charm now. Thanks for the tutorial!
I am trying to generate the pdf file of a webpage(for example:www.google.com) with the help of TCPDF.But unable to get the attached stylesheets and images attached with the webpage.how can i do that or in other words how can i get the exact pdf as the webpage is?
Hi Silky,
I think you’re looking for the same script. TCPDF is used to generate dynamic PDF files from the scratch. If you like to convert a HTML page into a PDF you need something else. Search google for “html to pdf”
Can I use TCPDF to fill in PDF Form file ? Not creating from the scratch. Because I’ve already have the PDF Form file that user usually fill it with Adobe Acrobat. But now I want to fill it automatically from mysql data in php webpage.
Hi,
You can’t do that with TCPDF :(
Someone mentioned that this is possible with “mpdf”. If this is not what your looking for, try a search in google for “php pdf forms”. I’m sure there are some free packages too.
Hello,
mayby i lost something,
I need put to pdf page with dynamic data – form with data as effect of asking database (typical)
url adres is too dynamic with f.ex. http://www.pttk.pl/ks3/index.php?dok_plik_1_nazwa=&kat1=12&kat2=&kadencja=
haw can i do that?
Please explain a little bit more, do you need to create a PDF with the data from your database or do you like to convert the HTML page into a PDF?
(for the last one check the comments at the top)
Is there a way to grab the physical width of a string?
I’m trying to put together a dynamic font size based on the string width. Currently what I do is use the number of characters to make a guess on when to decrease the font size, but that’s not accurate since I’m not using a mono-spaced font.
Hello Bryan,
why do you need this? A PDF document is build with cells. Maybe your need the multi-line function instead. (changing the font-size to get ALL chars into one row is so ugly ;))
Hi,
When I go over a special amount of rows in the array the page is doing weird.
I get a page per row than and all rows on page 1.
You can test it by copying the array rows and add about 6 times more of it….
That should be fixed in some way but I can’t figure out how.
Thanks!
Hello Matt,
that’s right. You need to count the rows and after X rows you need to add the code for a new page.
This is how it works ;)
Hi Olaf,
I tried that, but something goes wrong there, also with the header modification that I set.
Do you have an example how you would do it ?
Would be great!
Thanks!
Hi Matt,
posting a snippet without to test it makes no sense (sorry I’m currently very busy)
Check this function “TCPDF::SetAutoPageBreak” and you need to count the value “$currY”. If this value is bigger or equal a specific number you need to add a page (and maybe a different page header).
Hi Olaf,
I have searched a lot of things, but multiple pages seems to be a “bug” or at least a bad documented function.
There are some half workarounds, but not even these will fix it.
Cheers,
Matt
Hi Matt,
I’m sorry that I’m not able to provide an example.
I did something like this before with FPDF and it should work the same. Think about how a word document with a footer and header functions.
With PHP and PDF it works the same, after a specific Y value is reached a page break is done. Maybe you should try something simple:
Create simple header and footer functions and than create a loop with numbers or simple text. Just something that tells you when the page break is done.
Hi Olaf,
It’s what you say, and there might start the problem, see this:
http://www.jonathanlbrown.com/2011/07/17/tcpdf-paging-those-multicells/
So you are actually between the auto and manual pagebreak.
Hi Matt,
I can imagine that paging of multicells is a problem. The cells in PDF aren’t smart, if you like to do that you need to test the text length in PHP before the page break will happen (don’t ask me how, lol)
Dear Olaf!!! If I use many invoice rows, the pages 2, 3, 4 etc. are shown incorrectly. So: http://klavier-gesang-hannover.de/example_067.pdf Why? Please, help me!
Hi Eugen,
I know creating “nice looking” PDF files using TCPDF or FPDF is not so easy. I did this once with FPDF a view years ago. Currently I’m to busy to write some new PHP code which is able to add new PDF pages if required. But it’s on my list, I’m sorry that I don’t have a better answer for you (you’re not the only one). In the mean time check the example from the FPDF website, it’s not the same but the concept is similar.
Hi,
I’ve just spent a whole day trying to output a pdf with Zend, using Zend_Pdf (what a hell I can not just simply center text!!! The default x and y positions are bottom left of the page, but who’s making a page from bottom to top???), TCPDF (file does not begin by ‘%PDF), and mPDF (worked two minutes after I’ve installed it).
So, thanks to Q.
And thanks to Olaf, because I’ve found what I was looking for on his webpage.
Hi Nicolas,
I don’t get it why Zend_PDF is so limited, is it the missing documentation or because no one like to use it? You’re right TCPDF is the right choice: copy the class, create an object and your ready :)
I’m glad that my article was helpfull.
Hi Nicolas,
I don’t get it why Zend_PDF is so limited, is it the missing documentation or because no one like to use it? You’re right TCPDF is the right choice: copy the class, create an object and your ready :)
I’m glad that my article was helpful.
Hi Olaf,
Zend documentation is a pity… I’ve learned Zend with the help of webpages like yours.
Thanks for helping and sharing, and being present after all this to answer comments ans questions ;)
You’re welcome… I’m using several classes from the Zend framework, but it’s a much to heavy framework, it would be great if there are better resources. Maybe they have to much competitors ;)
I need to create multiline text into pdf conversion using php. I know how to display a single line:
How can I use the multiline function in php?
Hi,
the multi line/cell is a common TCPDF function check this example:
This is a good introduction but several things have change since it was initially written including better support for SVG and EPS images. However, my biggest suggestion would be to not force everything in PHP if other languages can achieve a better output. For instance Java has superior PDF capabilities with its numerous libraries.