Print page with javascript

Discussion in 'JavaScript' started by lukefowell89, Nov 17, 2010.

  1. #1
    I have a problem!

    I need to be able to print a page from a ExtJS Dashboard system I am developing, which I am adding a print button to which will bring up the print dialog.

    I have also set up a stylesheet for print (@media = print) which hides everything except the canvas I would like to print!

    The problems are as follows....

    - ActiveXObject for WScript.Shell wont work for some reason! I need to be able to set the page set up to landscape automatically! I also want to reduce all the margins to 2! Which I am guessing the only way is to use ActiveXObject

    - Even when I have the page set to landscape, some of my page still gets cut off horizontally!

    -Also vertically, my page wil only print the page which can be seen on the screen, it will not print anything under that

    So anyone got any solutions to any of my problems?

    Thanks
     
    lukefowell89, Nov 17, 2010 IP
  2. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #2
    if for an internal tool, jsPrintSetup - https://addons.mozilla.org/en-US/firefox/addon/8966/ - is an amazing plugin that bridges the api between javascript and the printer. of course, for it to work you need firefox and the plugin so its not for production sites. i use it a fair bit for internal tools though...
     
    Last edited: Nov 18, 2010
    dimitar christoff, Nov 18, 2010 IP
  3. lukefowell89

    lukefowell89 Peon

    Messages:
    182
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #3
    Thanks for your reply!

    The problem is that this web application is being shipped as part of our software product to our customers around the world. Therefore needing it to be compliant between at least IE, firefox and chrome.

    What I have done so far is brought the page to be displayed, converted it into an XML document. Stored it using localStorage then sent them to a print preview page where the XML is parsed and used to display all the data exacly as positioned by the user with absolute positions, widths, heights and style format

    This all works perfectly. What I need to get working is how I am going to deal with printing a page where the canvas is wider than a normal page width?

    It is too small to scale down (tryed this, scaling all the X, Y, Width, Height's down by 25% etc. or Printable Width / Max Width then multiple all the XY,Width and EHight byt hat. And using a Math.round function to round the ratio to a round number.

    What I want to do, is print off anything that is over the printable area, on a 2nd page. e.g. anything over 1050px; print just the remaining part off on a 2nd page.

    I thought I could do this by inserting the whole document twice into 2 divs, 1 of these divs is pulled left by -1050px; only showing the remaining section. This div is then hidden from view on teh normal style sheet. I then using a print style sheet (@media print) and display it for print as well as using page-breaks-before: always to make the page break before the 2nd div therefore assuring it is printed on a new page.

    This doesnt seem to work thou :S Can anyone see anything wrong with my code?

    XMLCreate Class:
    
    function XMLCreate()
     {
     	this.encoding = '';
    	this.rootNode = '';
    	this.xmlDoc = '';
    	this.xmlArray = [];
    	this.status = [];
    	
    	this.setRoot = function(name)
    	{
    		this.rootNode = name;
    	};
    	this.createNode = function(name, opened)
    	{
    		this.noNew = false;
    		var statusIndex = this.status.length;
    		if(this.status[statusIndex-1])
    			{
    				if(statusIndex > 0)
    				{
    					if(this.status[statusIndex-1][0] == 'close')
    					{
    						this.noNew = true;
    					}
    				}
    			}
    		if (this.noNew) {
    			console.log('close nodes')
    		}
    		else {
    			var statusIndex = this.status.length;
    			var index = this.xmlArray.length;
    			if (opened) {
    				name2 = '<' + name;
    				this.status.push(['close', name]);
    				this.xmlArray[index] = name2;
    			}
    			else {
    				name2 = '<' + name + '>';
    				this.status.push(['end', name]);
    				this.xmlArray[index] = name2;
    			}
    		}
    	};
    	this.closeNode = function() 
    	{
    		var statusIndex = (this.status.length)-1;
    		
    		if (statusIndex > -1) {
    			var closeAction = this.status[statusIndex][0];
    			var closeElement = this.status[statusIndex][1];
    			if (closeAction == "end") {
    				var closeNode = '</' + closeElement + '>';
    				this.status.splice(statusIndex, 1);
    			}
    			else if (closeAction == "close") {
    				var closeNode = '>';
    				this.status[statusIndex] = ['end', closeElement]
    			}
    			var index = this.xmlArray.length;
    			this.xmlArray[index] = closeNode+'\n';
    			
    		}
    	};
    	this.createAttr = function(name, value)
    	{
    		this.allowAttr = false;
    		var statusIndex = this.status.length;
    		if(this.status[statusIndex-1])
    			{
    				if(statusIndex > 0)
    				{
    					if(this.status[statusIndex-1][0] == 'close')
    					{
    						this.allowAttr = true;
    					}
    				}
    			}
    		if(this.allowAttr)
    		{
    			var index = this.xmlArray.length;
    			this.xmlArray[index] = ' '+name+'="'+value+'"';
    		}
    	};
    	this.textValue = function(value)
    	{
    		this.allowText = false;
    		var statusIndex = this.status.length;
    		if(this.status[statusIndex-1])
    			{
    				if(statusIndex > 0)
    				{
    					if(this.status[statusIndex-1][0] == 'end')
    					{
    						this.allowText = true;
    					}
    				}
    			}
    		if(this.allowText)
    		{
    			var index = this.xmlArray.length;
    			this.xmlArray[index] = value+'\n';
    		}
    	};
    	
    	this.createXML = function(rootNode)
    	{
    		if (this.status.length == 0) {
    			if (rootNode == '') {
    				var xmlDocMain = '<?xml version="1.0" encoding="UTF-8"?>@';
    			}
    			else {
    				this.setRoot(rootNode);
    				var xmlDocMain = '<?xml version="1.0" encoding="UTF-8"?>\n<' + this.rootNode + '>\n@\n</' + this.rootNode + '>';
    			}
    			
    			var xmlDoc = '';
    			for (x = 0; x < this.xmlArray.length; x++) {
    				xmlDoc = xmlDoc + this.xmlArray[x];
    			}
    			this.xmlDoc = xmlDocMain.replace('@', xmlDoc);
    			localStorage.setItem(rootNode, escape(this.xmlDoc)); 
    		}
    	};
     }
    
    
    Code (markup):
    Creating XML on localStorage:
    var componentStore = Ext.StoreMgr.item('canvasComponentsStore');
    					var xmlPrint = new XMLCreate();
    					componentStore.each( function(rec) {
    						
    						var height = rec.get('item').height;
    						var width = rec.get('item').width;
    						var x = rec.get('item').x;
    						var y = rec.get('item').y;
    						var style = rec.get('item').style;
    						var type = rec.get('item').type;
    						var text = rec.get('item').text;
    						
    						xmlPrint.createNode('component', true);
    						xmlPrint.createAttr('height', height);
    						xmlPrint.createAttr('width', width);
    						xmlPrint.createAttr('x', x);
    						xmlPrint.createAttr('y', y);
    						xmlPrint.createAttr('type', type);
    						xmlPrint.createAttr('style', style);
    						xmlPrint.createAttr('value', text);
    						xmlPrint.closeNode();
    						xmlPrint.closeNode();
    					});
    					xmlPrint.createXML('compstore');
    					window.open('print_preview.html')
    
    Code (markup):
    Print Preview Page (Renders HTML):
    
    <html>
    	<head>
    		
    		<style>
    			body 
    			{
    				font-size: 16px;
    				font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
    				padding: 15px;
    			}
    			#printcontrols
    			{
    				position: fixed;
    				top: 5px;
    				left: 5px;
    				background: url(images/black.png) repeat;
    				width: 110px;
    				height: 18px;
    				color: #fff;
    				padding: 15px;
    				font-size: 14px;
    				cursor: pointer;
    				-moz-border-radius: 15px;
    				border-radius: 15px;
    				z-index: 9999;
    			}
    			
    			#page1
    			{
    				clear:both;
    				position: relative;
    			}
    			
    			#page2
    			{
    				clear:both;
    				page-break-before: always;
    				position: relative;
    				visibility: hidden;
    			}
    			
    			#closepreview
    			{
    				position: fixed;
    				top: 5px;
    				left: 155px;
    				background: url(images/black.png) repeat;
    				width: 95px;
    				height: 18px;
    				color: #fff;
    				padding: 15px;
    				font-size: 14px;
    				cursor: pointer;
    				-moz-border-radius: 15px;
    				border-radius: 15px;
    				z-index: 9999;
    			}
    			@media print
    			{
    				.hidden
    				{
    					display:none;
    					visibility:hidden;
    					filter:alpha(opacity=0);
    					-moz-opacity:0;
    					-khtml-opacity: 0;
    					opacity: 0;
    				}
    				body
    				{
    					padding: 0;
    				}
    				
    				#page2
    				{
    					visibility: visible;
    				}
    				
    			}
    		</style>
    	</head>
    	<body>
    		<div id="printcontrols" class="hidden" onclick="window.print();">
    			Print Document		
    		</div>
    		<div id="closepreview" class="hidden" onclick="window.close();">
    			Close Preview	
    		</div>
    		<div id="page1">
    
    		</div>
    		
    		<div id="page2">
    
    		</div>
    		<script>
    
    		var xmlDoc = unescape(localStorage.getItem('compstore'));
    		var xmlobject = (new DOMParser()).parseFromString(xmlDoc, "text/xml");
    		var components = xmlobject.getElementsByTagName('component');
    		var maxWidth = 0;
    		var page1content = document.getElementById('page1');
    		var page2content = document.getElementById('page2');
    		for(i=0; i<components.length; i++)
    		{
    			var x = components[i].getAttribute('x');
    			x = parseInt(x);
    			var y = components[i].getAttribute('y');
    			y = parseInt(y);
    			var width = components[i].getAttribute('width');
    			width = parseInt(width);
    			var height = components[i].getAttribute('height');
    			height = parseInt(height);
    			var type = components[i].getAttribute('type');
    			var style = components[i].getAttribute('style');
    			if(style == 'undefined' || style == null)
    			{
    				style = '';
    			}
    			var value = components[i].getAttribute('value');
    			
    			if(maxWidth < (x+width))
    			{
    				maxWidth = (x + width);
    			}
    			var ratio = Math.round(1020/maxWidth);
    			x = x*ratio;
    			width = width*ratio;
    			style = style + ' font-size: 12px; padding-top: 3px;';
    		
    			page1content.innerHTML = page1content.innerHTML  + '<div style="position: absolute; top: '+y+'px; left: '+x+'px; width: '+width+'px; height: '+height+'px; '+style+'">'+value+'</div>';
    			page2content.innerHTML = page2content.innerHTML  + '<div style="position: absolute; top: '+y+'px; left: '+(x-1020)+'px; width: '+(width-1020)+'px; height: '+height+'px; '+style+'">'+value+'</div>';
    		}
    		localStorage.removeItem('compstore');
    		</script>
    	</body>
    </html>
    
    Code (markup):
    Thanks!
     
    lukefowell89, Nov 18, 2010 IP
  4. r.pointing

    r.pointing Peon

    Messages:
    24
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Hello Export
    Javascript that automatically prints the page when your visitor clicks the button.
     
    r.pointing, Dec 4, 2010 IP
  5. lukefowell89

    lukefowell89 Peon

    Messages:
    182
    Likes Received:
    2
    Best Answers:
    0
    Trophy Points:
    0
    #5
    If you read my first post, actually printing wasnt the issue, it was trying to change the page orientation
     
    lukefowell89, Mar 11, 2011 IP