Asudahlah.com

Programming, tutorials, mechatronics, operating systems, and other tech stuff

PHP FPDF Use text wrapping in table with MultiCell Table

7 comments
When we make a table in pdf using PHP FPDF library, basically we build it individually cell by cell. It is of course not as convenience as making a table using xml language such as HTML table. And the major drawbacks of using Cells is it's not able to wrap or break text as it overflow the defined cell width.

MultiCell

However, there is a method in FPDF library called MultiCell which allows us to make a Cell that wraps it's content, in short, it will break the text and make a new line when the text exceed it's width, thus multiplies it's height accordingly. But it doesn't works the same way with Cell, especially the positioning as the height varies according to it's content.

To make a table using MultiCell, we need to find out how much lines needed in a row as every cell in a row should have same height. And then we need to define where to put next cell, we can do this by calculating current cell position and offset it with it's dimension.

Don't want the math? FPDF MultiCell Table Class to the rescue.

FPDF Founder, Olivier Plathey have provided a FPDF extension class to make table from MultiCell named PDF_MC_Table. You can copy it from here :
https://github.com/gemul/fpdf-multicell-table/blob/master/pdf_mc_table.php

To use it, change the main fpdf.php file path to your FPDF library directory.
<?php
//call main fpdf file
require('fpdf18/fpdf.php');
//create new class extending fpdf class
class PDF_MC_Table extends FPDF {
...

Then in your script, include the pdf_mc_table.php file, not fpdf.php file.

<?php
//include pdf_mc_table.php, not fpdf17/fpdf.php
include('pdf_mc_table.php');
...

Next, create a new object from PDF_MC_Table Class.

...
//make new object
$pdf = new PDF_MC_Table();
...

From this point onward, you can use $pdf to build your pdf structure as usual. It doesn't change any functionaly of FPDF but instead it does add new ones.

Build the pdf table with MultiCell.

Like usual, you can add pages, use cell to build your content, and finally call Output() to render your pdf. Please read Generate Printable Invoice in PHP using FPDF library for more information.
And when it comes to make a multicell table, you need to:
  1. Set Font

    This is important to calculate length of the text.
    ...
    //add page, set font
    $pdf->AddPage();
    $pdf->SetFont('Arial','',14);
    ...
    
  2. Define the columns width.

    The column width is defined in array manner using SetWidths() method. The number of element should match the number of column.
    ...
    //set width for each column (6 columns)
    $pdf->SetWidths(Array(20,40,40,30,20,40));
    ...
    
  3. Set the line height.

    Use SetLineHeight() to define line height. This height will be used globally in our table. What we need to define here is height of line, not the row height. For example, if we define the line height to 5, and the cell with greatest line number in a row require 3 lines, then the height of the entire row will be 5 * 3 = 15.
    ...
    //set line height. This is the height of each lines, not rows.
    $pdf->SetLineHeight(5);
    ...
    
  4. Set the columns alignment (optional).

    This is optional. The default alginment of the cell is Left. You can define column alignment using SetAligns() method in array manner, with 'L' or empty string for Left (default), 'R' for Right, 'C' for Center, 'J' for justified. Also note that even if you only want to change only one column, you need to define all of them because number of array elements should match the number of columns.
    For example, when we want to make second column right aligned and third column centered, we use:
    ...
    //set alignment
    $pdf->SetAligns(Array('','R','C','','',''));
    ...
    
  5. Make the table header with standard Cell.

    To make it look like a proper table, add a table heading using standard cell with same number of columns and same widths for each cell respectively. Make the font bold if you like, or change the fill color to distinct it from table body. In this example, i will only make it bold.
    ...
    
    //add table heading using standard cells
    //set font to bold
    $pdf->SetFont('Arial','B',14);
    $pdf->Cell(20,5,"ID",1,0);
    $pdf->Cell(40,5,"First Name",1,0);
    $pdf->Cell(40,5,"Last Name",1,0);
    $pdf->Cell(30,5,"Email",1,0);
    $pdf->Cell(20,5,"Gender",1,0);
    $pdf->Cell(40,5,"Address",1,0);
    //add a new line
    $pdf->Ln();
    //reset font
    $pdf->SetFont('Arial','',14);
    ...
    
    Add a new line after that and do not forget to change the font back to normal.
  6. Write each row with Row() method.

    Then write the data row by row with Row() method also in array manners. The class will take care of the math.
    ...
    //loop the data
    foreach($data as $item){
     //write data using Row() method containing array of values.
     $pdf->Row(Array(
      $item['id'],
      $item['first_name'],
      $item['last_name'],
      $item['email'],
      $item['gender'],
      $item['address'],
     ));
     
    }
    ...
    
That's it. And don't forget to call $pdf->Output(); method to see the result.

And always keep in mind to never output anything in your script, so no empty line before "<?php", no echo, var_dump(), print() whatsoever. Even an error report or php warning will break your pdf file thus make it a corrupted pdf.

Except when you want to debug your code, you can freely output anything but comment out $pdf->Output(); line to prevent pdf render.

Known limitations.

However, as far as i know, there are some limitation in this method which is:
  1. Borders.
    Because the border is drawn using Rect() behind the scene, you may need some tweaking if you wish to change its style, color or size.

Further explanation and tutorial video.

For further explanation on how this class works behind the scene, please watch my tutorial video on youtube here :
https://youtu.be/pELrw9P5ywM
Also check out my PHP PDF Video Tutorial playlist here:
https://www.youtube.com/playlist?list=PLHCU7DCP4jhxnxV4Ub4YDqWiZ061t183c

7 comments :

Post a Comment

How to make ip address calculator with java netbeans

2 comments

This one is a video tutorial. And here is the source code which is used in the tutorial.
For step-by-step instruction, please watch the video.


int prefix = Integer.valueOf(mask.getText());
int pos = prefix / 8; //important octet position
int rem = prefix % 8; //binary digit of importan octet

String binIpFull = "";
String subBinary = "";
String subBinaryFull = "";
String binnetidFull = "";
String binbcidFull = "";
String netmaskFull = "";
String netidFull = "";
String bcidFull = "";

//loop to generate binary mask from octet pos
for (int i = 1; i & lt; = 8; i++) {
 if (i & lt; = rem) {
  subBinary += "1";
 } else {
  subBinary += "0";
 }
}

//netmask (integer version of subBinary
int netmask = Integer.parseInt(String.valueOf(subBinary), 2);

//ip octets array
int[] oct = {
 Integer.valueOf(oct1.getText()),
 Integer.valueOf(oct2.getText()),
 Integer.valueOf(oct3.getText()),
 Integer.valueOf(oct4.getText())
};

//binary of important octet
String binOct = String.format("%8s", Integer.toBinaryString(oct[pos])).replace(' ', '0');

String binNetId = "";
String binBcId = "";

for (int i = 0; i & lt; 8; i++) {
 String binPointer = subBinary.substring(i, i + 1);
 if (binPointer.equals("1")) {
  binNetId += binOct.substring(i, i + 1);
  binBcId += binOct.substring(i, i + 1);
 } else {
  binNetId += "0";
  binBcId += "1";
 }
}

//loop to generate display-ready strings
for (int i = 0; i & lt; = 3; i++) {
 binIpFull += String.format("%8s", Integer.toBinaryString(oct[i])).replace(' ', '0');
 if (i < pos) { = ""
  subbinaryfull += "11111111"; = ""
  netmaskfull = "" += "255"
  binnetidfull = ""
  ','
  0 ');="" binbcidfull="" netidfull="" bcidfull="" ="" }else="" if(i="">pos){
  subBinaryFull += "00000000";
  netmaskFull += "0";
  binnetidFull += "00000000";
  binbcidFull += "00000000";
  netidFull += "0";
  bcidFull += "1";
 } else {
  subBinaryFull += subBinary;
  netmaskFull += String.valueOf(netmask);
  binnetidFull += binNetId;
  binbcidFull += binBcId;
  netidFull += Integer.parseInt(String.valueOf(binNetId), 2);
  bcidFull += Integer.parseInt(String.valueOf(binBcId), 2);
 }
 if (i != 3) {
  subBinaryFull += ".";
  netmaskFull += ".";
  binnetidFull += ".";
  binbcidFull += ".";
  netidFull += ".";
  bcidFull += ".";
  binIpFull += ".";
 }
}
subBinLabel.setText(subBinaryFull);
netMaskLabel.setText(netmaskFull);
netBinLabel.setText(binnetidFull);
bcBinLabel.setText(binbcidFull);
netIdLabel.setText(netidFull);
bcIdLabel.setText(bcidFull);
ipBinLabel.setText(binIpFull);


You can watch the video here:



2 comments :

Post a Comment

[PHP FPDF] How to Integrate QR Code in PDF Generation

3 comments
After long time without update, this time, i will post about how to use QR Code in PDF created with PHP FPDF Library.


For those who doesn't know what QR Code is, here's a brief summary. QR Code, invented in 1994 by the Japanese company Denso Wave, is a 2 dimensional version of barcode. And unlike barcode, QR Code are capable to store alphanumeric, symbol, binaries, and kanji. Right now, it's widely used in many application such as product identification, payment, data entries, advertisement, announcement, and many more. In short, it looks like this:
And you can scan it with your smartphone to get information contained in it.

Now, let's get back to the topic.

In my previous tutorial about How to add barcode to PDF created with PHP FPDF, we extend our FPDF class so it could provide barcode generation suport. But this time, we are using an entirely independent library called PHP QR Code by deltalab.
Download the PHP QR Code library here : http://sourceforge.net/projects/phpqrcode/files/

Then extract it to your working directory alongside the fpdf directory.

Then from the browser, try to open that directory to try the demos. If nothing goes wrong, you will be presented by something like this.


This is a general-purpose QR Code generator, which means you can use it in another project other than PDF.

Now, create a new php file in your working directory. Then make a blank pdf page out of it.
Please read Generate Printable Invoice in PHP using FPDF library if you haven't done so.

Add this code in your new file:
<?php
require_once("fpdf17/fpdf.php");

$pdf = new FPDF('P','mm','A4');

$pdf->AddPage();

$pdf->Output();
And the result should be a blank pdf page like this


Before we continue, there are 2 method to insert the QR Code into our PDF File. And both works by using FPDF Image method to insert an image in the pdf.

First method is by using a QR Code generator, second is generating a QR Code image file upon PDF Generation.

Let's try out the former.

Create a QR Code Generator.

Create a new php file, name it qr_generator.php. Then add these 2 simple lines of code in it.
<?php
require_once("phpqrcode/qrlib.php");

QRcode::png($_GET['code']);
Then try to access that file in browser and provide value to code parameter like this:
http://localhost/pdf/qr_generator.php?code=1234567
and you should get something like this
Congratulation, you've just made a general-purpose QR code generator. Now let's embed it into our PDF Generator.
Simply just add an image using FPDF Image method with that url as the image source parameter like this
<?php
require_once("fpdf17/fpdf.php");

$pdf = new FPDF('P','mm','A4');

$pdf->AddPage();

$pdf->Image("http://localhost/pdf/qr_generator.php?code=content here", 10, 10, 20, 20, "png");

$pdf->Output();
and you should get something like this

Just change the code parameter and image position to suit what you need. With this, you can use the qr code generator for your other project. Just make sure to secure your generator with secret key or tokens, i won't explain it here but to help you start, just use a simple IF statement to check if there are specified secret key passed in the GET request and immediately exit the code if it turns out false.

Now let's try the second method.

Create the QR Code upon PDF Generation.

With this method, instead of using separate QR code generator. We are generating the QR image inside our PDF generator script, store the QR image in a directory, then insert the image using FPDF Image method.

First, include the phpqrcode library in your file.
Then create the QR code using QRcode::png method
QRcode::png("coded number here","test.png");
Note that i added second parameter to the method which indicates that the resulted file will be saved as an png file with that name.

Then add that image in the pdf using Image method like usual. So your final code should look like this (I've provided comments to help explain each parts of the code) :
<?php
//include the libraries
require_once("fpdf17/fpdf.php");
require_once("phpqrcode/qrlib.php");

//create a QR Code and save it as a png image file named test.png
QRcode::png("coded number here","test.png");

//pdf stuff
$pdf = new FPDF('P','mm','A4');
$pdf->AddPage();

//this is the first method
$pdf->Image("http://localhost/pdf/qr_generator.php?code=content here", 10, 10, 20, 20, "png");

//this is the second method
$pdf->Image("test.png", 40, 10, 20, 20, "png");

//and absolutely don't forget this one
$pdf->Output();

And if nothing goes wrong, you should get something like this:
IMPORTANT NOTICE : In real world practice, it's necessary to use different file name for each PHP session because the png file would be replaced at every request. And also don't forget to remove the file regularly to prevent it from bloating your storage with a lot of unused png file.

Both method have its pros and cons, just pick whichever method suit your need.

Finally, please check out my youtube video here and please kindly subscribe to my channel for more tutorials. https://www.youtube.com/watch?v=XFpuxgpUXgE



3 comments :

Post a Comment

How to add barcode to PDF created with PHP FPDF

24 comments
This time, i'm about to explain how to add barcode to your generated pdf file. This tutorial requires you to understand the basics how to make / generate pdf file in PHP using FPDF library beforehand. So please read Generate Printable Invoice in PHP using FPDF library if you haven't done so.

Why and what is barcode?

Barcode is an optical, machine-readable numeric data consisting of series of black and white bars with varying thickness. Commonly used in label which requires fast-reading done by machine or computer. Barcode can minimize user's manual input so instead of showing only numeric id on your, let's say, invoice. You can also provide barcoded id. So the user, especially in fast-paced transaction environment can just scan it using barcode reader instead of manual input with keyboard. And here's how to add barcode to your generated PDF file in PHP FPDF library.

Barcode support for PHP FPDF library.

There are no built-in barcode support in PHP FPDF library. However, with a custom class, we can add a barcode support. Here i have prepared a barcode class in my github repository you can download right away here: https://github.com/gemul/fpdf-barcode.
There are a lot of barcode standard format, but here we will only use 2 format. EAN13, and UPC_A format which is a commonly used barcode standard.
EAN stands for European Article Number which is a barcode symbology standard and numbering system used in global trade to identify a specific retail product type, in a specific packaging configuration, from a specific manufacturer. While the UPC stands for Universal Product Code which is also a barcode symbology that is widely used in the United States, Canada, United Kingdom, Australia, New Zealand, in Europe and other countries for tracking trade items in stores. Both can hold 12 digit of integer (last digit in EAN13 is a check number so you can only keep 12 digit). For more explanation about barcode standard, you can look it up in wikipedia.

Using custom PHP FPDF class to make a barcode.

First, you need the PHP FPDF library, here i used  FPDF version 1.7 which you can download here.
Then download or copy-paste the fphp_barcode.php file from my repository to your local webserver.
Open the file and make sure that the second line refer to your fpdf.php file which comes with your fpdf library. On my case, the folder structure looks like this:
\htdocs\pdf\
         |-fpdf\
         |  |-fpdf.php
         |-fpdf_barcode.php
 So the "require" path should look like this:

require('fpdf/fpdf.php');

Next, make a new file in the same directory as your fpdf_barcode.php file named barcode-test.php then copy this script into it.

<?php
require('fpdf_barcode.php');

$pdf = new PDF_BARCODE('P','mm','A4');

$pdf->AddPage();

//EAN13 test
$pdf->EAN13(10,10,'123456789012',5,0.5,9);
$pdf->EAN13(10,20,'123456789012',5,0.35,9);
$pdf->EAN13(10,30,'123456789012',10,0.35,9);

//UPC_A test
$pdf->UPC_A(100,10,'123456789012',5,0.5,9);
$pdf->UPC_A(100,20,'123456789012',5,0.35,9);
$pdf->UPC_A(100,30,'123456789012',10,0.35,9);

$pdf->Output();

Save it then see the result in your browser. If nothing goes wrong, it should be like this:

Now, what does the code above do?
First line, we include the fpdf_barcode.php file, not the usual fpdf.php file. We're using a custom class here.
Next, make a PDF_BARCODE object, not FPDF object. With the same parameter as usual. Then add a page. And at the last line, don't forget to output the result. (Please read this fpdf basic if you haven't done so).
With these lines, you are properly made a single page blank PDF file.

<?php
//call the fpdf_barcode.php, not the usual fpdf.php. We're using a custom class here.
require('fpdf_barcode.php'); 

//define a PDF_BARCODE object, not FPDF object. With portrait orientation, milimeters unit, and A4 size.
$pdf = new PDF_BARCODE('P','mm','A4');

//add a page
$pdf->AddPage();

//the content goes here

//Output the result
$pdf->Output();

In the pdf_barcode class, there are 2 methods called EAN13 and UPC_A. As the name implies, the former is to make a EAN13 barcode and the later is for UPC_A.

For EAN13, use :
$pdf->EAN13(float x, float y, string barcode [, float h [, float w[, int font_size]]])

And For UPC_A :
$pdf->UPC_A(float x, float y, string barcode [, float h [, float w[, int font_size]]])

x is the abscissa of barcode. Which means the horizontal position of the top-left corner of the barcode.
y is the ordinate of barcode. The vertical position of the top-left corner of the barcode.
barcode is the value of barcode, consists of 12 digits integer.
h is the height of barcode. Default value is 16.
w is the width of a bar. Default value is 0.35.
font_size is the font size of the number below barcode.

So, this line :

$pdf->EAN13(10,10,'123456789012',5,0.5,9);
Means that we make an EAN13 Barcode at position of 10mm from left and 10mm from top of the page. The barcode contains 123456789012 and the height is 5 and the bar width (not the whole barcode width) is 0.5. And the text which says the integer value below the barcode have a size of 9 points.

If by any chance you're still confused after following this tutorial, please do enjoy this video-version of this tutorial. And if you want the source code, feel free download it from the link provided in the description or ask me in the comment section of aforementioned video.

24 comments :

Post a Comment