It gives many problem to export any html or div to pdf when it content charts because many pdf converter library do not support chart container and not able to convert that chart or html div to pdf.
Here I am going to sort out these problem.
These blog show you how to download Charts like google charts and others, to pdf formate at client side.
Here we use three script or technique:
1. First of all we draw charts at html div as we done in previous blog.
2. Then we convert that chart to Image(canvas) using google api (canvg.js) .
3. Convert whole html page to canvas using html2canvas library.
4.download that canvas (as image) to pdf formate using jspdf librar.
//Import html2canvas and jspdf library to you local folder.
//<Script That help to achieve our goal>
1. //script of charts that you use as google api that we use in previous blog.
//convert chart to Image(canvas) used to invoke canvg(); method
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
//convert html page to canvas using html2canvas library
<script type="text/javascript" src="../js/html2canvas.js"></script>
//Now export canvas to pdf using jspdf library.
<script type="text/javascript" src="/oltapp/js/FileSaver.js"></script>
<script type="text/javascript" src="/oltapp/js/jspdf.js"></script>
<script type="text/javascript" src="/oltapp/js/jspdf.plugin.addimage.js"></script>
<script type="text/javascript" src="/oltapp/js/jspdf.js"></script>
<script type="text/javascript" src="/oltapp/js/jspdf.plugin.addimage.js"></script>
Note: we do not need to import all js of jspdf .
lets take an example to fully understand.
Example code:
<html>
<head>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/canvg.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/rgbcolor.js"></script>
<script type="text/javascript" src="http://canvg.googlecode.com/svn/trunk/StackBlur.js"></script>
<script type="text/javascript" src="../js/html2canvas.js"></script>
<script type="text/javascript" src="../js/FileSaver.js"></script>
<script type="text/javascript" src="../js/jspdf.js"></script>
<script type="text/javascript" src="../js/jspdf.plugin.addimage.js"></script>
<script type="text/javascript" src="../js/FileSaver.js"></script>
<script type="text/javascript" src="../js/jspdf.js"></script>
<script type="text/javascript" src="../js/jspdf.plugin.addimage.js"></script>
<script type="text/javascript">
function export_PDF(chartContainer, imgContainer) {
//main Div Hide
var el = document.getElementById( 'chart_Container' );
el.parentNode.removeChild( el );
el.parentNode.removeChild( el );
//Chart to Image
var doc = chartContainer.ownerDocument;
var img = doc.createElement('img');
img.src = getImgData(chartContainer);
while (imgContainer.firstChild) {
imgContainer.removeChild(imgContainer.firstChild);
}
var img = doc.createElement('img');
img.src = getImgData(chartContainer);
while (imgContainer.firstChild) {
imgContainer.removeChild(imgContainer.firstChild);
}
imgContainer.appendChild(img);
//Pdf Creation
var divElements = document.getElementById('expotPdfDiv).innerHTML;
//Get the HTML of whole page
var oldPage = document.body.innerHTML;
//Reset the page's HTML with div's HTML only
document.body.innerHTML =
"<html><head><title></title></head><body>" +
divElements + "</body>";
//convert whole html page to canvas
//Get the HTML of whole page
var oldPage = document.body.innerHTML;
//Reset the page's HTML with div's HTML only
document.body.innerHTML =
"<html><head><title></title></head><body>" +
divElements + "</body>";
//convert whole html page to canvas
html2canvas(document.body, {
onrendered: function(canvas) {
// canvas is the final rendered <canvas> element
var myImage = canvas.toDataURL("image/JPEG").slice('data:image/jpeg;base64,'.length);
// Convert the data to binary form
myImage = atob(myImage)
myImage = atob(myImage)
//new object of jspdf and save image to pdf.
var doc = new jsPDF();
doc.addImage(myImage, 'JPEG', 0, 0, 200,200);
doc.save('pdfName.pdf');
}
});
}
function getImgData(chartContainer)
{
var chartArea = chartContainer.getElementsByTagName('svg')[0].parentNode;
var svg = chartArea.innerHTML;
var doc = chartContainer.ownerDocument;
var canvas = doc.createElement('canvas');
canvas.setAttribute('width', chartArea.offsetWidth);
canvas.setAttribute('height', chartArea.offsetHeight);
canvas.setAttribute(
'style',
'position: absolute; ' +
'top: ' + (-chartArea.offsetHeight * 2) + 'px;' +
'left: ' + (-chartArea.offsetWidth * 2) + 'px;');
doc.body.appendChild(canvas);
canvg(canvas, svg);
var imgData = canvas.toDataURL("image/JPEG");
var data = canvas.toDataURL('image/JPEG').slice('data:image/JPEG;base64,'.length);
{
var chartArea = chartContainer.getElementsByTagName('svg')[0].parentNode;
var svg = chartArea.innerHTML;
var doc = chartContainer.ownerDocument;
var canvas = doc.createElement('canvas');
canvas.setAttribute('width', chartArea.offsetWidth);
canvas.setAttribute('height', chartArea.offsetHeight);
canvas.setAttribute(
'style',
'position: absolute; ' +
'top: ' + (-chartArea.offsetHeight * 2) + 'px;' +
'left: ' + (-chartArea.offsetWidth * 2) + 'px;');
doc.body.appendChild(canvas);
canvg(canvas, svg);
var imgData = canvas.toDataURL("image/JPEG");
var data = canvas.toDataURL('image/JPEG').slice('data:image/JPEG;base64,'.length);
// Convert the data to binary form
data = atob(data)
canvas.parentNode.removeChild(canvas);
return imgData;
}
data = atob(data)
canvas.parentNode.removeChild(canvas);
return imgData;
}
</script>
</head>
<body>
<div id="expotPdfDiv">
<div id="chart_Container" >
----
--- //Here is script for making chart at chart_Container div.
---
</div>
<div id="chart_image"></div> //div where chart image genrate
<button Onclick=" export_PDF(document.getElementById('chart_Container'), document.getElementById('chart_image')); " > Download PDF</button>
</div>
</body>
</html>
Hi Sachin,
ReplyDeleteCame here via your reply on the Google forums. Your solution is just what I'm looking for.
I can't seem to get it working though. I've tried to apply your solution to a default graph, see: http://www.dannyoosterveer.nl/test_canvas2pdf/canvas2pdf.html
Though I get this error:
----- error in canvg.js
TypeError: Illegal constructor.
var color = new RGBColor(this.value);
-----
Can you see what I'm doing wrong? And/or do you have a live demo?
hey Danny ,
DeleteI see your page,and trying to solve your problem as soon as possible .
and thanks to comment .
Hi Sachin,
DeleteThat's great, thanks in advance!
Hey Danny,
DeleteAdd extra java script for canvas .
http://canvg.googlecode.com/svn/trunk/rgbcolor.js
http://canvg.googlecode.com/svn/trunk/StackBlur.js
Try this,and let me know. Is it working or not.
Hi Sachin,
ReplyDeleteThanks for your reply.
I've added the two javascripts. It gets passed the RGBcolor error now.
Unfortunately, there's another error that pops up:
---------------------
InvalidCharacterError: String contains an invalid character
myImage = atob(myImage)
---------------------
hey Danny,
ReplyDeletejust paste that code in line 91 to 97 .and set pdf formate according to you
var myImage = canvas.toDataURL("image/JPEG").slice('data:image/jpeg;base64,'.length);
myImage = atob(myImage)
you having space in line 93
Deletevar myImage = canvas.toDataURL("image/JPEG").slice('data:image /jpeg;base64,'.length);
thats why you got error. I think it is working this time.
Ah, must have been some copy paste error, I missed that, my bad.
DeleteI was just able to generate a PDF, hurray!
Any idea why the dimensions are screwed up? (see http://www.dannyoosterveer.nl/test_canvas2pdf/pdfName.pdf)
Great man now you generated pdf ,
Deleteand for improve your pdf graphics check jspdf library . :)
http://jsfiddle.net/spurgeom/je3Fy/ here's a working solution
ReplyDeletehelpful but same as my above code.
DeleteHai Sachin Nahar it is working for single Google chart.but not for multiple charts that i binded dynamically. How can i display multiple charts in pdf format plz reply
ReplyDeleteyes we can use it for multiple charts also ..convert all charts to canvas .
DeleteCan you please give us the workable solution for multiple charts also?
DeleteYes. Is there a way to add another chart to the pdf?
ReplyDeletehi Sachin this is working only for svg tag of google chart,is there way to working for whole chartContener and one thing is not working in touch device ,so please tell me is ther any way by which we can do this..
ReplyDeleteHi Sachin, I am using your example to create pdf for my google chat where i am using ajax and json. Everything working fine in Firefox browser, but not working in IE9.
ReplyDeleteI am getting 'undefined' for chartContainer.getElementsByTagName('svg')[0] in the getImgData(chartContainer) function. I have added all the js libraries that you have mentioned above.
Do you know if i am missing something?
Hi Sachin,
ReplyDeleteCan you please give me workable solution for exporting multiple charts into pdf?
Thanks in advance
I am facing the same issue. Exporting multiple charts on dashboard to pdf. Any help plz.
ReplyDeleteThank you.
Hi Sachin,
ReplyDeleteI am getting an error, "Cannot read property 'parentNode' of null" on the following line(Line no. 18):
el.parentNode.removeChild( el );
Can you please help me in resolving this issue?
Thanks in advance,
Shashank
i hv tried the sample code bt getting error Cannot read property 'parentNode' of undefined
ReplyDeleteHi sachin,
ReplyDeletei want to also add datatable of the chart with chart and download pdf of both div together can u help plz.
Hi sachin,
ReplyDeletesample code is running perfectly one time,on downloading d copy of the page 2nd time getting error,Uncaught TypeError: Cannot read property 'parentNode' of null plz,help
Hi Sachin
ReplyDeleteThank you
If I have a URL, www.anysite.com and I want to export the contents of that site to a PDF,
Is it possible with jsPDF?
Thank you
Hi Sachin
ReplyDeleteThank you
If I have a URL, www.anysite.com and I want to export the contents of that site to a PDF,
Is it possible with jsPDF?
Thank you
Hi Sachin
ReplyDeleteThank you
If I have a URL, www.anysite.com and I want to export the contents of that site to a PDF,
Is it possible with jsPDF?
Thank you