jsPDF icon indicating copy to clipboard operation
jsPDF copied to clipboard

How to fix content cut off issues in jspdf ?

Open dhanushkumarsivaji opened this issue 2 years ago • 8 comments

I am using jspsf and html2canvas to convert the components into a PDF.

Below is the code for that,

  function generatePDF() {
    const input = document.getElementById("pdf");
    html2canvas(input, {
      logging: true,
      letterRendering: 1,
      scale: 2,
      windowWidth: 1440,
      useCORS: true
    }).then((canvas) => {
      var imgData = canvas.toDataURL("image/png");
      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, "jpeg", 0, position, imgWidth, imgHeight);
      heightLeft -= pageHeight;
      while (heightLeft >= 0) {
        position = heightLeft - imgHeight;
        doc.addPage();
        doc.addImage(imgData, "jpeg", 0, position, imgWidth, imgHeight);
        heightLeft -= pageHeight;
      }

      const pages = doc.internal.getNumberOfPages();

      for (let j = 1; j < pages + 1; j++) {
        let horizontalPos = imgWidth / 2; //Can be fixed number
        let verticalPos = pageHeight - 10; //Can be fixed number
        doc.setPage(j);
        doc.setFontSize(10);
        doc.text(`${j} of ${pages}`, horizontalPos, verticalPos, {
          align: "center" //Optional text styling});
        });
      }

      doc.save("output.pdf");
    });
  }

is there any way to fix this issue? Please help me to solve this one.

Here you can get the working demo link - https://codesandbox.io/s/react-component-to-pdf-goe-page-cutting-3rnl29?file=/src/App.js:412-1697

dhanushkumarsivaji avatar Sep 19 '22 12:09 dhanushkumarsivaji

@eKoopmans we require your help on this

dhanushkumarsivaji avatar Sep 19 '22 15:09 dhanushkumarsivaji

I think you need add bottom margin to heightLeft

glebov21 avatar Sep 20 '22 08:09 glebov21

yes, but the values and charts might get added based on the API data. Its a dynamic component

dhanushkumarsivaji avatar Sep 20 '22 18:09 dhanushkumarsivaji

Hi there, I've been working on the same problem. You could checkout css properties break-after and break-before using print media query to force an element into the next page.

cljaray avatar Sep 21 '22 13:09 cljaray

Hi @cljaray, Thanks for the comment. Do you have any working examples?

dhanushkumarsivaji avatar Sep 21 '22 13:09 dhanushkumarsivaji

Not at the moment, because I'm still working on it. But you could try to wrap the elements you want on the next page in a div with the following class

CSS @media print { .documentToPdf { break-before: always; } }

You could also wrap the elements before the one you want on the next page with the following class

CSS @media print { .documentToPdf { break-after: always; } }

I'm sorry i don't have the working example, but as I said, I'm working on it too.

Please note that

cljaray avatar Sep 21 '22 14:09 cljaray

Thanks for helping @cljaray

dhanushkumarsivaji avatar Sep 21 '22 16:09 dhanushkumarsivaji

We tried adding the css class but it does not cause a page break.

AnthonyPhan avatar Oct 16 '22 08:10 AnthonyPhan

Did anyone find a solution ?

guio12 avatar Oct 25 '22 12:10 guio12

Hi @cljaray, are you able to fix this problem?

dhanushkumarsivaji avatar Oct 25 '22 17:10 dhanushkumarsivaji

@cljaray @AnthonyPhan @guio12 @dhanushkumarsivaji did u guys found any solution for this problem ?

ChamkhiAnas avatar Feb 09 '23 17:02 ChamkhiAnas

Unfortunately not, we ended up using a paid library instead.

AnthonyPhan avatar Feb 09 '23 22:02 AnthonyPhan

@AnthonyPhan can u give me the name of the paid library ?

ChamkhiAnas avatar Feb 10 '23 22:02 ChamkhiAnas

https://docs.telerik.com/kendo-ui/framework/pdf/overview

Worked really well and the generated PDF is much smaller, however it's very expensive.

AnthonyPhan avatar Feb 11 '23 05:02 AnthonyPhan

This issue is stale because it has been open 90 days with no activity. It will be closed soon. Please comment/reopen if this issue is still relevant.

github-actions[bot] avatar May 13 '23 01:05 github-actions[bot]

I wanted to share a solution I found for a common issue with jsPDF where text gets cut off at the end of a page when generating a PDF from HTML content. This can be particularly troublesome when dealing with dynamic or lengthy content.

After experimenting with various settings, I found a combination that works well to prevent text from splitting inappropriately across pages.

Here's the function I used to generate the PDF:

function downloadPdf() { let jsPdf = new jsPDF('p', 'pt', 'letter'); var htmlElement = pdfRef.current; // Reference to the HTML content which i wanna shown in pdf

const opt = {
    callback: function (jsPdf) {
        jsPdf.save("Test.pdf");
    },
    margin: [20, 20, 20, 20], // Set appropriate margins
    autoPaging: 'text', // Crucial for handling text flow across pages
    html2canvas: {
        allowTaint: true,
        letterRendering: true,
        logging: false,
        scale: 0.4, // Adjust the scale to fit content
    }, 
};

jsPdf.html(htmlElement, opt);

}

Key Points:

The autoPaging: 'text' option in jsPDF was particularly useful to ensure the text flows correctly from one page to another.

Adjusting the scale in html2canvas options helped fit the content properly within the PDF pages.

This approach worked well for my use case with dynamic content. I hope this solution helps others who are struggling with similar issues in jsPDF. Feel free to tweak the settings to suit your specific needs!

igagandeep avatar Jan 15 '24 17:01 igagandeep