I am not a Flex guy and I don’t think I will ever be. While searching I checked a couple of different ways of how to generate PDF with Javascript in Adobe Air.
The one I liked called AlivePDF. At the very beginning I found it really difficult to work with. The latest compiled release does not have many important methods mentioned in the class documentation. Yes there is an SVN to get it and compile but as I mentioned before I am not Flex guy and setting up the whole Flex runtime just to compile this library was a big deal.
Anyway below I have created some instructions how you can implement PDF functionality to your Air App with Javascript. It is still a little limited compare lets say to PDFBox java driven PDF generator.

Installation

  1. Download the latest release of AlivePDF, none RC version: http://code.google.com/p/alivepdf/downloads/list
  2. Unzip it to your local drive
  3. Inside the /bin folder you will find *.swc file. Unzip it one more time. If you having problems unzipping it, rename it to *.zip first.
  4. Now copy file library.swf into your air project. You can rename it if required.

Include library.swf into your HTML page the way you include Javascript files:

<script type="application/x-shockwave-flash" src="/alivePDF/library.swf"></script>

AlivePDF jQuery plugin

Below I developed jQuery plugin to generate PDF files using AlivePDF. Please save it into a separate javascript file and make sure it is included into the page.

(function( $ ) {
  $.fn.pdf = function( ) { 	  

	if (!window.runtime)  {
		  alert("Window Runtime is not defined!");
		  return this;
	}

	/*In order for us to call classes and methods from library.swf we have to
		always use the full path to it, like: new window.runtime.org.alivepdf.pdf.PDF();
		Let's not do that and create a simple list of aliases that we can extend when
		we need to.
	*/
	this.Document = window.runtime.org.alivepdf.pdf.PDF;
	this.Display = window.runtime.org.alivepdf.display.Display;
	this.Layout = window.runtime.org.alivepdf.layout.Layout;
	this.Orientation = window.runtime.org.alivepdf.layout.Orientation;
	this.Size = window.runtime.org.alivepdf.layout.Size;
	this.Unit = window.runtime.org.alivepdf.layout.Unit;
	this.Download = window.runtime.org.alivepdf.saving.Download;
	this.Method = window.runtime.org.alivepdf.saving.Method;
	this.ImageFormat = window.runtime.org.alivepdf.images.ImageFormat;
	this.ResizeMode = window.runtime.org.alivepdf.images.ResizeMode;
	this.ColorSpace = window.runtime.org.alivepdf.images.ColorSpace;
	this.Resize = window.runtime.org.alivepdf.layout.Resize;
	this.Grid = window.runtime.org.alivepdf.data.Grid;
	this.GridColumn = window.runtime.org.alivepdf.data.GridColumn;
	this.DataGrid = window.runtime.fl.controls.DataGrid;
	this.DataProvider = window.runtime.fl.data.DataProvider;
	this.TextFormat = window.runtime.flash.text.TextFormat;
	this.RGBColor = window.runtime.org.alivepdf.colors.RGBColor;
	this.Fonts = window.runtime.org.alivepdf.fonts;

	 /* PUBLIC methods */

	/* newDocument() - method creates a new alivePDF object
	 *
	 * @param orientation - object alivePDF.Orientation.PORTRAIT
	 * @param unit - object alivePDF.Unit.MM
	 * @param size - object alivePDF.Size.A4
	 * @return this
	 *
	*/
	this.newDocument = function( orientation, unit, size) {
		//Document is a class object reference to alivePDF
		this.Document = new window.runtime.org.alivepdf.pdf.PDF(orientation, unit, size);
		return this;
	};

	/* save() - method saves PDF locally
	 *
	 * @param f - air file object
	 * @return this
	 *
	*/
	this.save = function(f) {
		var fs = new air.FileStream();
		fs.open(f, air.FileMode.WRITE);
		fs.writeBytes(this.Document.save(this.Method.LOCAL));
		fs.close();
		return this;
	};

	/* imageAsBytes() - methods reads local image and returns bytearray
	 *
	 * @param f - air file object
	 * @return this
	 *
	*/
	this.imageAsBytes = function(f) {
		var ba = new air.ByteArray();
		stream = new air.FileStream();
		stream.open(f, air.FileMode.READ);
		stream.readBytes(ba);
		stream.close();
		return ba;
	};

	return this;
  };
})( jQuery );

Generating PDF

Now we got to our final point. I will assume that you have done all the steps above.

//init library
var PDF = new $(document).pdf();

//init base font
var baseFont 	= new PDF.Fonts.CoreFont(PDF.Fonts.FontFamily.ARIAL);
var blackColor 	= new PDF.RGBColor(0x000000);
var whiteColor 	= new PDF.RGBColor(0xFFFFFF);
var lineHeight 	= 5;
var fontSize 	= 10;
var fullWidth 	= 200;
var x 			= 0;
var y 			= 0;

//lets configure the PDF document
var DOC = PDF.newDocument(PDF.Orientation.PORTRAIT, PDF.Unit.MM, PDF.Size.A4).Document;
DOC.setDisplayMode(PDF.Display.FULL_WIDTH); //set to show full screen zoom
DOC.setTitle("ajax911 AlivePDF Tutorial");
DOC.setAuthor("Dima Svirid");
DOC.setCreator("Ajax911.com");

//create first page
DOC.addPage();
DOC.setMargins(5,5,5,5);

//lets keep height of the page for furher use
var pageH		= DOC.getPage(1).h;

Create Title

DOC.setFontSize(20); //set title font size
DOC.addCell(fullWidth, 20, "This is my Title", null, null, "C");
DOC.setFontSize(fontSize);	//reset font size back to normal

Embed Image

DOC.addImageStream(
	PDF.imageAsBytes(air.File.applicationDirectory.resolvePath("images/test.png")),
	PDF.ColorSpace.DEVICE_RGB,
	new PDF.Resize("FitToPage", "left")
);

PDF Content

//to add some content to PDF we can use addCell method
//DOC.textStyle(whiteColor); //change color if you want to
DOC.addCell(fullWidth, lineHeight, "Text goes here", 0, 1, "L", 1);
DOC.textStyle(blackColor); //set font color	

//you can also include HTML content, however it is very limited and I found it useless.
//Also make sure your HTML does not have broken tags otherwise it will throw an error
DOC.writeFlashHtmlText(lineHeight, "<b>My Strong text</b>");

Save and output PDF

When you think PDF is ready, let’s save it locally and show it to the reader.

//save the document
PDF.save(air.File.applicationStorageDirectory.resolvePath("pdfname.pdf"));		

var fl = air.File.applicationStorageDirectory.nativePath.toString() + "/pdfname.pdf";
var f = new air.File(fl);

if(air.HTMLLoader.isSupported &&
	     air.HTMLLoader.pdfCapability == air.HTMLPDFCapability.STATUS_OK && f.exists)
{
	window.open('file:///' + fl, "pdfWindow", "height=600, width=900, top=0, left=0");
}
else if (air.HTMLLoader.pdfCapability != air.HTMLPDFCapability.STATUS_OK) {
	if(confirm("Oops..we could not locate Adobe Reader and it is required for PDF support. Would you like to install it now?")) {
		var request = new air.URLRequest("http://get.adobe.com/reader/");
    	air.navigateToURL(request, "_blank");
	}
}
else
{
   alert("Oops..there is been a problem generating PDF.")
}

References

http://alivepdf.bytearray.org/
http://alivepdf.bytearray.org/alivepdf-asdoc/class-summary.html

Dima Svirid

Software architect. Ajax/Javascript, HTML5, Android, iPhone/iPad, JAVA, PHP, Cold Fusion, SQL, Air, Flash, Open source software, Frameworks

More Posts

Follow Me:

 

One Response to Generating PDF Documents with Adobe Air Javascript SDK and jQuery

  1. Hi,

    How can I achieve Pdf handling using Jquery/PHP/Flash/HTML5? In that the user should able to drag an image onto the pdf and save it in database for future reference. Is there any out there for doing the same? Thanks in advance.

Leave a Reply