Customizing PDF generated using jQuery DataTables plugin

Datetime:2016-08-23 02:54:03          Topic: jQuery  ActionScript           Share

Introduction

In this tip, we will see how we can customize the DataTables plug-in of jQuery to add our custom header and footer in the PDF. We can add plain text or image as a header same as footer of the PDF. DataTables is a very powerful plug-in that enables you to quickly and easily enhance your tables and it provides an awesome feature to generate PDF, CSV and Excel file at client side. By default, simple PDF is generated by DataTables but if you want to show any image/company logo as PDF header and any disclaimers as footer, then this facility is not provided by DataTables and this is very important to show images/logo in the PDF file.

Before starting this, I am assuming that you are well versed with DataTables , if not then you can visit a very awesome article written by Jovan Popovic at http://www.codeproject.com/Articles/194916/Enhancing-HTML-tables-using-a-JQuery-DataTables-pl .

DataTables internal usages .swf file and this .swf file contains the ActionScript code to generate PDF/CSV/Excel file so if we want to add our custom images/disclaimers, then we need to modify the ActionScript code. Following things are required to start:

Using the Code

After gathering all the required files, lets start's with the code. First, we will modify the ActionScript code and will generate the swf file for us to use with DataTables plug-in.

Open the " ZeroClipboardPdf.as " file using any text editor or using Adobe Flash Builder 4.6. In this example, we are using NotePad++ to modify the " ZeroClipboardPdf.as " file. When you open " ZeroClipboardPdf.as " in NotePad++, you will see all the ActionScript code that is used to generate PDF files at client side. It is not required to be a good programmer to understand the ActionScript code, an average programmer can also understand it. In the ZeroClipboardPdf.as file, you will find a private function " configPdf " like below:

private function configPdf():PDF
	{
		var
			pdf:PDF,
			i:int, iLen:int,
			splitText:Array    = clipText.split("--/TableToolsOpts--\n"),
			opts:Array         = splitText[0].split("\n"),
			dataIn:Array       = splitText[1].split("\n"),
			aColRatio:Array    = getProp( 'colWidth', opts ).split('\t'),
			title:String       = getProp( 'title', opts ),
			message:String     = getProp( 'message', opts ),
				
...

In the above code, we are accessing the values of all the properties that are used for PDF generation and these values are passing from JavaScript. So here, we will also add new properties for header and footer and the values of the same will pass from JavaScript. For example, below is the modified code after adding 2 new properties, i.e., headerImage and footerMessage .

private function configPdf():PDF
	{
		var
			pdf:PDF,
			i:int, iLen:int,
			splitText:Array    = clipText.split("--/TableToolsOpts--\n"),
			opts:Array         = splitText[0].split("\n"),
			dataIn:Array       = splitText[1].split("\n"),
			aColRatio:Array    = getProp( 'colWidth', opts ).split('\t'),
			title:String       = getProp( 'title', opts ),
			message:String     = getProp( 'message', opts ),
			headerImage:String = getProp( 'imageData', opts ),
			footerMessage:String = getProp( 'footerMessage', opts ),
				
...

Here, headerImage will store the base64 string value of header image (as of now, you need to use only JPG images no other formats are supported due to background transparency issue.) and footerMessage will store the footer disclaimer text.

After the above code, you will find the below code in " ZeroClipboardPdf.as " file.

/* Create the PDF */
			pdf = new PDF( Orientation[orientation.toUpperCase()], 
				Unit.MM, Size[size.toUpperCase()] );
			pdf.setDisplayMode( Display.FULL_WIDTH );
			pdf.addPage();
			iPageWidth = pdf.getCurrentPage().w-20;
			pdf.textStyle( new RGBColor(0), 1 );

This is the starting code to generate PDF, after this code, you can add your own code to add the header image. First, import the following namespace, then add the following code in your ActionScript file.

import mx.utils.Base64Decoder;

/* Add the header image if there is one in the top */
		if ( headerImage != "" )
		{
			var decoder:Base64Decoder = new Base64Decoder();
			decoder.decode(headerImage);
			var ba:ByteArray = decoder.toByteArray();
			pdf.addImageStream(ba,"DeviceRGB",null,0,0,
						iPageWidth,35,0,1,"Normal",null);
		}
			
		/* Add the title / message if there is one in the top */
		pdf.setFont( new CoreFont(FontFamily.HELVETICA), 14 );
		if ( title != "" )
		{
			pdf.writeText(11, title+"\n");
		}

This code will add an image in the PDF. You can check the AlivePDF documentation for more options/high resolution images, full PDF documentation is available at http://alivepdf.bytearray.org/alivepdf-asdoc/org/alivepdf/pdf/PDF.html .

Now, it's time to add footer text, for this, you need to find the below code in ZeroClipboardPdf.as file. 

var grid:Grid = new Grid(
				dataOut,                  /* 1. data */
				iPageWidth,               /* 2. width */
				100,                      /* 3. height */
				new RGBColor (0xE0E0E0),  /* 4. headerColor */
				new RGBColor (0xFFFFFF),  /* 5. backgroundColor */
				true,                     /* 6. alternateRowColor */
				new RGBColor ( 0x0 ),     /* 7. borderColor */
				.1,                       /* 8. border alpha */
				null,                     /* 9. joins */
				columns                   /* 10. columns */
			);
			
	pdf.addGrid( grid, 0, y, true );

The above code is creating a grid with the table data provided from JavaScript and adding this grid to PDF object. After this, we can add our code for footer, like below:

pdf.newLine(20);    // Adding a blank line

pdf.setFont( new CoreFont(FontFamily.HELVETICA), 6 ); //Font family for footer text
pdf.textStyle( new RGBColor(0xB3B3B3), 1 ); // Font color and size

if ( footerMessage != "" )
{
    pdf.writeText(3, footerMessage+"\n"); //Line height and footer text
}

Now, it's time to compile this ActionScript file and generate swf file for our use. Follow the steps given below:

mxmlc -static-link-runtime-shared-libraries=true 
	-library-path=C:\flex_sdk_4.6\frameworks\libs ZeroClipboard.as
  • Extract the Flex sdk at C:\flex_sdk_4.6
  • CopyZeroClipboardPdf.as to C:\flex_sdk_4.6\bin directory and AlivePdf.swc to C:\flex_sdk_4.6\frameworks\libs directory.
  • Open command prompt under the path C:\flex_sdk_4.6\bin
  • Execute the compile command
  • After compiling, you will get a swf file at location: C:\flex_sdk_4.6\bin\ZeroClipboard.swf
  • Now you can use this newly generated swf file with your DataTables

You can set the swf file path in your JavaScript like below: 

$(document).ready(function() {
    $('#example').DataTable( {
        dom: 'T<"clear">lfrtip',
        tableTools: {
            "sSwfPath": "../swf/copy_csv_xls_pdf.swf" //This is name of the swf file.
        }
    } );
} );

Now, you need to override the click event of PDF button because we need to pass the 2 extra parameters which we used in ActionScript file, i.e., headerImage and footerMessage . Below is the code snippet:

var tableTools = new $.fn.dataTable.TableTools(table, {
       "aButtons": [{
           "sExtends": "collection",
           "sButtonText": "Download Reports",
              
           "aButtons": [{
               "sExtends": "csv",
               "sButtonText": "Download as CSV",                   
               "sFileName": "Result.csv"
           },
           {
               "sExtends": "pdf",
               "sButtonText": "Download as PDF",
               "sFileName": "Result.pdf",
               "sNewLine": "\n",                    
               "fnClick": function (nButton, oConfig, flash) {
                       this.fnSetText(flash, "title:" + this.fnGetTitle(oConfig) + "\n" 
			+ "footerMessage:" + 
			"This will be our disclaimer Text. We can add very long text also" + 
			"\n" 
			+ "headerImage:" + 
			"/9j/4AAQSkZJRgABAQEAlgCWAAD/2wBDAAoHBwkHBgoJCAkLCwoMDxkQDw4ODx4WFxIZJCAmJSMgIyIoLTkwKCo......" + 
			"\n" 
			+ "colWidth:" + this.fnCalcColRatios(oConfig) + "\n" 
			+ "orientation:" + oConfig.sPdfOrientation + "\n" 
			+ "size:" + oConfig.sPdfSize + "\n" 
			+ "--/TableToolsOpts--\n" + this.fnGetTableData(oConfig));                         
                }
           }]
      },
           {
               "sExtends": "print",
               "sButtonText": "Print This Report"        
           }]
   });

In the above code snippet, we are overriding the click event of PDF by passing 2 extra parameters. You can use any online tool to convert image to base64 string or you can write any server side or client side code for this.

Points of Interest

JavaScript library can greatly simplify HTML manipulation. It is an amazing framework! and AlivePDF, a very useful ActionScript3 library for PDF generation at client side. It is simply awesome. 





About List