Pregunta

I am using jsPDF in my site to generate PDFs. But now I have multiple DIVs to print in a single PDF. which may take 2 to 3 pages.

For example:

<div id="part1">
  content
</div>

<div id="part2">
  content
</div>

<div id="part2">
   content
</div>

my JS code

  • This works but not as I expected, It add a part of the content(which cannot be included in more than one page).
  • It removes html tags like br, h1 etc.
    function formtoPDF() {
      jsPDF.API.mymethod = function() {
        // 'this' will be ref to internal API object. see jsPDF source
        // , so you can refer to built-in methods like so:
        //   this.line(....)
        //   this.text(....)
      };
      var doc = new jsPDF();
      doc.mymethod();
      var pdfPart1 = jQuery('#genPDFpart1');
      var pdfPart2 = jQuery(".ltinerary");
      var pdfPart3 = jQuery("#domElementHTML");
      var specialElementHandlers = {
        '#loadVar': function(element, renderer) {
          return true;
        }
      };
      doc.fromHTML(pdfPart1.html() + pdfPart3.html() + pdfPart3.html(), 15, 15, {
        'width': 170,
        'elementHandlers': specialElementHandlers
      });
      doc.output('save', 'Download.pdf');
    }

Can I have a solution for this. Thanks in advance pals .

¿Fue útil?

Solución

I have the same working issue. Searching in MrRio github I found this: https://github.com/MrRio/jsPDF/issues/101

Basically, you have to check the actual page size always before adding new content

doc = new jsPdf();
...
pageHeight= doc.internal.pageSize.height;

// Before adding new content
y = 500 // Height position of new content
if (y >= pageHeight)
{
  doc.addPage();
  y = 0 // Restart height position
}
doc.text(x, y, "value");

Otros consejos

here's an example using html2canvas & jspdf, although how you generate the canvas doesn't matter--we're just going to use the height of that as the breakpoint on a for loop, in which a new page is created and content added to it.

after the for loop, the pdf is saved.

function makePDF() {

   var quotes = document.getElementById('container-fluid');
   html2canvas(quotes).then((canvas) => {
        //! MAKE YOUR PDF
        var pdf = new jsPDF('p', 'pt', 'letter');

        for (var i = 0; i <= quotes.clientHeight/980; i++) {
            //! This is all just html2canvas stuff
            var srcImg  = canvas;
            var sX      = 0;
            var sY      = 980*i; // start 980 pixels down for every new page
            var sWidth  = 900;
            var sHeight = 980;
            var dX      = 0;
            var dY      = 0;
            var dWidth  = 900;
            var dHeight = 980;

            window.onePageCanvas = document.createElement("canvas");
            onePageCanvas.setAttribute('width', 900);
            onePageCanvas.setAttribute('height', 980);
            var ctx = onePageCanvas.getContext('2d');
            // details on this usage of this function: 
            // https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images#Slicing
            ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);

            // document.body.appendChild(canvas);
            var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);

            var width         = onePageCanvas.width;
            var height        = onePageCanvas.clientHeight;

            //! If we're on anything other than the first page,
            // add another page
            if (i > 0) {
                pdf.addPage(612, 791); //8.5" x 11" in pts (in*72)
            }
            //! now we declare that we're working on that page
            pdf.setPage(i+1);
            //! now we add content to that page!
            pdf.addImage(canvasDataURL, 'PNG', 20, 40, (width*.62), (height*.62));

        }
        //! after the for loop is finished running, we save the pdf.
        pdf.save('Test.pdf');
  });
}

I found the solution on this page: https://github.com/MrRio/jsPDF/issues/434 From the user: wangzhixuan

I copy the solution here: // suppose your picture is already in a canvas

      var imgData = canvas.toDataURL('image/png');

      /*
      Here are the numbers (paper width and height) that I found to work. 
      It still creates a little overlap part between the pages, but good enough for me.
      if you can find an official number from jsPDF, use them.
      */
      var imgWidth = 210; 
      var pageHeight = 295;  
      var imgHeight = canvas.height * imgWidth / canvas.width;
      var heightLeft = imgHeight;

      var doc = new jsPDF('p', 'mm');
      var position = 0;

      doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
      heightLeft -= pageHeight;

      while (heightLeft >= 0) {
        position = heightLeft - imgHeight;
        doc.addPage();
        doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
        heightLeft -= pageHeight;
      }
      doc.save( 'file.pdf');
 var doc = new jsPDF('p', 'mm');

 var imgData = canvas.toDataURL('image/png');
 var pageHeight= doc.internal.pageSize.getHeight();
 var pageWidth= doc.internal.pageSize.getWidth();

 var imgheight = $('divName').height() * 25.4 / 96; //px to mm
 var pagecount = Math.ceil(imgheight / pageHeight);

 /* add initial page */
 doc.addPage('l','mm','a4');
 doc.addImage(imgData, 'PNG', 2, 0, pageWidth-4, 0);

 /* add extra pages if the div size is larger than a a4 size */
 if (pagecount > 0) {
     var j = 1;
     while (j != pagecount) {
         doc.addPage('l','mm','a4');
         doc.addImage(imgData, 'PNG', 2, -(j * pageHeight), pageWidth-4, 0);
         j++;
     }
 }

You can use html2canvas plugin and jsPDF both. Process order: html to png & png to pdf

Example code:

jQuery('#part1').html2canvas({
    onrendered: function( canvas ) {
        var img1 = canvas.toDataURL('image/png');
    }
});
jQuery('#part2').html2canvas({
    onrendered: function( canvas ) {
        var img2 = canvas.toDataURL('image/png');
    }
});
jQuery('#part3').html2canvas({
    onrendered: function( canvas ) {
        var img3 = canvas.toDataURL('image/png');
    }
});
var doc = new jsPDF('p', 'mm');
doc.addImage( img1, 'PNG', 0, 0, 210, 297); // A4 sizes
doc.addImage( img2, 'PNG', 0, 90, 210, 297); // img1 and img2 on first page

doc.addPage();
doc.addImage( img3, 'PNG', 0, 0, 210, 297); // img3 on second page
doc.save("file.pdf");
$( document ).ready(function() {    
$('#cmd').click(function() {
      var options = {
              pagesplit: true //include this in your code
      };
      var pdf = new jsPDF('p', 'pt', 'a4');
      pdf.addHTML($("#pdfContent"), 15, 15, options, function() {
        pdf.save('Menu.pdf');
      });
    });
});

This is my first post which support only a single page http://www.techumber.com/html-to-pdf-conversion-using-javascript/

Now, the second one will support the multiple pages. http://www.techumber.com/how-to-convert-html-to-pdf-using-javascript-multipage/

Below is my code but the problem is that the document doesn't split to display the other part of the document in a new page.

Please improve this code.

<script type='text/javascript'>
$(document).on("click", "#btnExportToPDF", function () {
    var table1 =
    tableToJson($('#table1')[0]),
    cellWidth =42,
    rowCount = 0,
    cellContents,
    leftMargin = 2,
    topMargin = 12,
    topMarginTable =5,
    headerRowHeight = 13,
    rowHeight = 12,
    l = {
        orientation: 'p',
        unit: 'mm',
        format: 'a3',
        compress: true,
        fontSize: 11,
        lineHeight: 1,
        autoSize: false,
        printHeaders: true
    };

    var doc = new jsPDF(l,'pt', 'letter');

    doc.setProperties({
        title: 'Test PDF Document',
        subject: 'This is the subject',
        author: 'author',
        keywords: 'generated, javascript, web 2.0, ajax',
        creator: 'author'
    });
    doc.cellInitialize();

    $.each(table1, function (i, row)
    {
        rowCount++;

        $.each(row, function (j, cellContent) {

            if (rowCount == 1) {
                doc.margins = 1;
                doc.setFont("Times New Roman");
                doc.setFontType("bold");
                doc.setFontSize(11);

                doc.cell(leftMargin, topMargin, cellWidth, headerRowHeight, cellContent, i)
            }
            else if (rowCount == 2) {

                doc.margins = 1;
                doc.setFont("Times ");
                doc.setFontType("normal");
                // or for normal font type use ------ doc.setFontType("normal");

                doc.setFontSize(11);

                doc.cell(leftMargin, topMargin, cellWidth, rowHeight, cellContent, i);
            }
            else {

                doc.margins = 1;
                doc.setFont("Times  ");
                doc.setFontType("normal ");
                doc.setFontSize(11);
                doc.cell(leftMargin, topMargin, cellWidth, rowHeight, cellContent, i);
                // 1st=left margin    2nd parameter=top margin,     3rd=row cell width      4th=Row height
            }
        })
    })
    doc.save('sample Report.pdf');
});

function tableToJson(table) {

    var data = [];

    // first row needs to be headers
    var headers = [];

    for (var i=0; i<table.rows[0].cells.length; i++) {
        headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi,'');
    }

    // go through cells
    for (var i=1; i<table.rows.length; i++) {

        var tableRow = table.rows[i];

        var rowData = {};

        for (var j=0; j<tableRow.cells.length; j++) {
            rowData[ headers[j] ] = tableRow.cells[j].innerHTML;
        }

        data.push(rowData);
    }

    return data;
}
</script>

Automatically not split data to multi pages. You may split manually.

If your ( rowCount * rowHeight ) > 420mm ( A3 Height in mm ) add new page function. ( Sorry I can't edit your code without run ) After add new page leftMargin, topMargin = 0; ( start over ) I added sample code with yours. I hope it's right.

else {
    doc.margins = 1;
    doc.setFont("Times  ");
    doc.setFontType("normal ");
    doc.setFontSize(11);
    if ( rowCount * rowHeight > 420 ) {
        doc.addPage();
        rowCount = 3; // skip 1 and 2 above
    } else {
        // now rowcount = 3 ( top of new page for 3 )
        // j is your x axis cell index ( j start from 0 on $.each function ) or you can add cellCount like rowCount and replace with
        // rowcount is your y axis cell index
        left = ( ( j ) * ( cellWidth + leftMargin );
        top = ( ( rowcount - 3 ) * ( rowHeight + topMargin );
        doc.cell( leftMargin, top, cellWidth, rowHeight, cellContent, i);
        // 1st=left margin    2nd parameter=top margin,     3rd=row cell width      4th=Row height
    }
}

You can convert html directly to pdf lossless. Youtube video for html => pdf example

         html2canvas(element[0], {
                    onrendered: function (canvas) {
                        pages = Math.ceil(element[0].clientHeight / 1450);
                        for (i = 0; i <= pages; i += 1) {
                            if (i > 0) {
                                pdf.addPage();
                            }
                            srcImg = canvas;
                            sX = 0;
                            sY = 1450 * i;
                            sWidth = 1100;
                            sHeight = 1450;
                            dX = 0;
                            dY = 0;
                            dWidth = 1100;
                            dHeight = 1450;
                            window.onePageCanvas = document.createElement("canvas");
                            onePageCanvas.setAttribute('width', 1100);
                            onePageCanvas.setAttribute('height', 1450);
                            ctx = onePageCanvas.getContext('2d');
                            ctx.drawImage(srcImg, sX, sY, sWidth, sHeight, dX, dY, dWidth, dHeight);
                            canvasDataURL = onePageCanvas.toDataURL("image/png");
                            width = onePageCanvas.width;
                            height = onePageCanvas.clientHeight;
                            pdf.setPage(i + 1);
                            pdf.addImage(canvasDataURL, 'PNG', 35, 30, (width * 0.5), (height * 0.5));
                        }
                        pdf.save('testfilename.pdf');
                    }
                });
var a = 0;
var d;
var increment;

for(n in array){
    d = a++;        

    if(n % 6 === 0 && n != 0){
        doc.addPage();
        a = 1;
        d = 0;
    }

    increment = d == 0 ? 10 : 50;
    size = (d * increment) <= 0 ? 10 : d * increment;

    doc.text(array[n], 10, size);
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top