11

I use Html2Canvas and then jsPdf to export the image.

This is the function:

function exportPdf() {
    content = $("#print");

    var useWidth = content.prop('scrollWidth');
    var useHeight = content.prop('scrollHeight');

    debugger;

    html2canvas((content), { width: useWidth, height: useHeight}).then(function (canvas) {
        debugger;
        var img = canvas.toDataURL("image/png");
        var doc = new jsPDF({
            unit:'px', 
            format:'a4'
        });

        debugger;
        doc.addImage(img, 'JPEG', 0, 0);
        doc.save('test.pdf');
    });
}

I think is taking in consideration the viewport, is like doing a printscreen, of course whatever is below the scroll it doesn't take it into consideration.

Any ideas?

user3442470
  • 409
  • 2
  • 6
  • 19

7 Answers7

22

Call

    window.scrollTo(0,0)

Before calling html2canvas, its seems its a bug but the window needs to be at the top for html2canvas to capture the entire DOM passed to it

10

It happens when window is scrolled. To work around this problem you can pass negative of whatever window is scrolled by.

html2canvas(htmlSource, {scrollY: -window.scrollY}).then(function(canvas) {

// Do Something here

});
Aakash Yadav
  • 585
  • 5
  • 8
3

Setting windowHeight and height worked for me:

Try like this:

html2canvas(htmlSource, {
     height: window.outerHeight + window.innerHeight,
     windowHeight: window.outerHeight + window.innerHeight,
     scrollY: -window.scrollY
}).then(function(canvas) {
    // Do Something here    
});
Rifky Niyas
  • 1,737
  • 10
  • 25
Adrita Sharma
  • 21,581
  • 10
  • 69
  • 79
2

One of the reason is already mentioned above that is window might be scrolled, so always add this line before u capture image using html2canvas

    window.scrollTo(0,0)

Another problem can be the resolution of image is more than a pdf page, for that you need to get the width and height of PDF document.

var width = doc.internal.pageSize.getWidth();
var height = doc.internal.pageSize.getHeight();

Use it for your image to fit the PDF document.

doc.addImage(imgData, 'JPEG', 0, 0, width, height);

If you want a dynamic sized image not to be distorted and keep the image width/height ratio

 var width = doc.internal.pageSize.getWidth();
 var height = doc.internal.pageSize.getHeight();

 let widthRatio = width / canvas.width;
 let heightRatio = height / canvas.height;

 let ratio = widthRatio > heightRatio ? heightRatio : widthRatio

Followed by

 doc.addImage(imgData, "PNG", 0, 0, canvas.width * ratio, canvas.height * ratio,);
Junaid Masood
  • 658
  • 11
  • 20
1

You can try something with the responsive way like :

if (screen.width < 1024) {
    document
      .querySelector("meta[name=viewport]")
      .setAttribute("content", "width=1200px");
  }

  let generatedPDFB64;
  //used the Printable HOC for capturing printable component with print-id attribute
  const printElement = document.querySelector(`div[print-id=${selector}]`);
  // convert the html to canvase
  const convertedCanvas = await html2canvas(printElement, {
    allowTaint: true,
    removeContainer: true,
    backgroundColor: null,
    imageTimeout: 15000,
    logging: true,
    scale: 2,
    scrollY: window.scrollTo({
      top: 0,
      behavior: 'smooth'
    }),
    useCORS: true
  });

  const contentDataURL = convertedCanvas.toDataURL("image/png");
  const imgWidth = 205;
  const pageHeight = 300;
  const imgHeight = (convertedCanvas.height * imgWidth) / convertedCanvas.width;
  let heightLeft = imgHeight;
  const shouldCompress = true

  let pdf = new jsPDF("p", "mm", "a4", shouldCompress); // A4 size page of PDF
  let position = 0;

   pdf.addImage(
    contentDataURL,
    "PNG",
    0,
    position,
    imgWidth,
    imgHeight,
    "print",
    "FAST"
  ); 
  heightLeft -= pageHeight;

  while (heightLeft >= 0) {
    position = heightLeft - imgHeight;
    pdf.addPage();
    pdf.addImage(
      convertedCanvas,
      0,
      position,
      imgWidth,
      imgHeight,
      "print",
      "FAST"
    );
    heightLeft -= pageHeight;
  }

  pdf.save("resume.pdf"); // Generated PDF

  if (screen.width < 1024) {
    document
      .querySelector("meta[name=viewport]")
      .setAttribute("content", "width=device-width, initial-scale=1");
  }

Ashif Zafar
  • 623
  • 5
  • 6
0

The only thing that worked for me, was to add the following code into my css.

This style code is used to prevent html2canvas limit the rendering to the viewable area.

.html2canvas-container { 
    width: 3000px; 
    height: 3000px; 
}
0

For my case, I added a class to make it fixed:

$("#print").addClass('ready-fix');

CSS:

.ready-fix {
    position: fixed !important;
    top: 0;
    left: 50%;
    z-index: 9999;
    -ms-transform: translate(-50%, 0);
    transform: translate(-50%, 0);
}

Then called "html2canvas", the image was no longer cropped:

html2canvas(document.querySelector("#print"), { scale: window.devicePixelRatio, allowTaint: true }).then(canvas => {
//code here
$("#print").removeClass('ready-fix');
})

Finally removed the fixed class.

Quốc Võ
  • 11
  • 2