Skip to content

Instantly share code, notes, and snippets.

@rajendarreddyj
Created February 6, 2017 06:23
Show Gist options
  • Save rajendarreddyj/e2cd8afd8ac57bf588c57b229d195b4d to your computer and use it in GitHub Desktop.
Save rajendarreddyj/e2cd8afd8ac57bf588c57b229d195b4d to your computer and use it in GitHub Desktop.
jspdf with html canvas
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hello world</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<h1>Hello world</h1>
<p id="ignorePDF">don't print this to pdf</p>
<div>
<div class="content-body">
<h2>Introduction</h2>
<p class="text-normal">The order in which commands to download external Cascading Style Sheets (CSS) files and JavaScript files are placed in an HTML page can affect how quickly the page is rendered and even whether the page is rendered at all.</p>
<p class="text-normal">When a CSS file is loaded before a JavaScript file, the page can begin rendering and the file downloads can happen in parallel which speeds up the rendering time.</p>
<p class="text-normal">If the order is reversed, the files are downloaded sequentially and the JavaScript file must finish loading completely before any other file can be downloaded. This means that the page cannot begin rendering until the JavaScript download is complete and the CSS file can begin loading.</p>
<p class="text-normal">This Best Practice Deep Dive looks at the issues involved with the order in which files are downloaded, tells you how AT&amp;T ARO can help identify when certain files are loaded in an inefficient order, and provides recommendations for downloading style sheets and scripts.</p>
<h2>Background</h2>
<p class="text-normal">As a developer building HTML 5 style apps or webpages, you can control the order that files are requested by your mobile app. It is important to consider the order you request the files in, because some ways are faster than others.</p>
<h2>The Issue</h2>
<p class="text-normal">Script files (such as JavaScript) are loaded sequentially unless asynchronous downloading is specified (for more information, see Asynchronous Load of JavaScript in HTML). Sequential (synchronous) download means that the entire script file must be downloaded before any other files can be downloaded and before any other instructions on the page, such as inline code or HTML, can be executed.</p>
<p class="text-normal">Another issue that can occur when a JavaScript file is loaded before a CSS file, is that any JavaScript code which relies on properties set in that CSS file can't be executed until both files have finished loading.</p>
<h2>Best Practice Recommendation</h2>
<p class="text-normal">The Best Practice Recommendation is to download CSS before script files, and to move SCRIPT tags to the bottom of the page whenever possible.</p>
<p class="text-normal">The AT&amp;T Application Resource Optimizer (ARO) can help you identify this potential file order problem. AT&amp;T ARO tests the HTML documents in your app and if a JavaScript file is loaded before a CSS file in the HEAD of an HTML document, the test fails and the name of the file is listed in the rest results.</p>
</div>
</div>
<input type="button" value="Print Div Contents" id="btnPrint" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.0.272/jspdf.debug.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.js"></script>
<script type="text/javascript">
function getPDFFileButton () {
// Select which div with id that need to be printed
// to print body $('body')
// here printing div with content id $("#content")
// using html canvas to save as required pdf to image to preserve css
return html2canvas($('body'), {
background: "#ffffff",
onrendered: function(canvas) {
var myImage = canvas.toDataURL("image/jpeg,1.0");
// Adjust width and height
var imgWidth = (canvas.width * 20) / 240;
var imgHeight = (canvas.height * 20) / 240;
// jspdf changes
var pdf = new jsPDF('p', 'mm', 'a4');
pdf.addImage(myImage, 'JPEG', 15, 2, imgWidth, imgHeight); // 2: 19
pdf.save('Download.pdf');
}
});
}
$("#btnPrint").on("click", function () {
getPDFFileButton ()
});
</script>
</body>
</html>
@SwethaEnixta
Copy link

SwethaEnixta commented Feb 15, 2018

Hi @rajendarreddyj,
How can we select multiple divs to print into 1 pdf ?

@Alvin-Prasla
Copy link

Alvin-Prasla commented Mar 28, 2018

@SwethaEnixta

function generatePDF() {

    // TODO: remove hard coded value
    var numberOfInnerDivs = 2;

    var deferreds = [];
    var doc = new jsPDF("p", "pt", "a4");
    for (let i = 1; i <= numberOfInnerDivs; i++) {
        var deferred = $.Deferred();
        deferreds.push(deferred.promise());
        generateCanvas(i, doc, deferred);
    }

    $.when.apply($, deferreds).then(function () { // executes after adding all images
        doc.save('Test.pdf');
    });
}

function generateCanvas(i, doc, deferred) {

    html2canvas($("#Div" + i)[0]).then(function (canvas) {
        var imgData = canvas.toDataURL("image/jpeg");
        doc.addImage(imgData, 'JPEG', 0, 20);
        doc.addPage();
        deferred.resolve();
    });
}
document.getElementById('PrintPDF').addEventListener('click', generatePDF);``

View Page

<section class="data-charts">
    <div class="col-md-8" id="Div1">
        <figure id="svgChart" class="svg-container">
        </figure>
    </div>
    <div class="col-md-4" id="Div2">
        <table id="myTable" class="display datatable"></table>
    </div>
</section>

@nazhad88
Copy link

nazhad88 commented Apr 1, 2018

Thanks a lot, it works well for me ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment