4

So, I wrote a small functionality to take a web page and print it beautifully with Index and page numbers on it (for A4 size). I have used the html2pdf and jspdf libraries to achieve this. All works well for fewer content webpages but when tested for live pages i.e large content pages, it prints blank pages.

I suspect, one of the libraries I have used isn't able to manage large data and behaving strangely. It would be helpful if someone could guide me to solve this or show me some alternative solutions.

The bare minimum sample code is available on Github: https://github.com/kamlekar/pdf-print
You can check by running locally that localhost/index.html works well (small content web page)
Whereas localhost/longpage.html shows blank pages and even prints all or some blank pages with wrong page numbers.

Related excerpt code:

async function getPrintReadyDocumentObjectFromHtmlElement(htmlElement) {
  return html2pdf()
    .from(htmlElement)
    .set(printFormatOptions)
    .toPdf()
    .get("pdf")
    .catch((err) => {
      console.error(err);
    });
}
Mr_Green
  • 40,727
  • 45
  • 159
  • 271
  • 2
    `html2canvas` is a dependency of `html2pdf` and canvases have maximum sizes imposed by browsers. See the related project: https://github.com/eKoopmans/html2pdf.js/projects/5 – morganney Oct 30 '22 at 03:06

1 Answers1

3

You are hitting the supported limits of html2canvas at least caused by something in the huge div ".PDF_print_container".

Tweaking printStyleSettings.scale and printStyleSettings.dpi can stretch the borders a little bit, but your document is that big, that the decreased settings will result in an unreadable PDF. Until the new renderer is available there will be no way around that limit.

The behavior is browser specific. Chrome fails silent, while Firefox reports that something went wrong:

Exception { name: "NS_ERROR_FAILURE", message: "", result: 2147500037, filename: "https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js", lineNumber: 2, columnNumber: 0, data: null, stack: "e@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:508673\n./node_modules/html2canvas/dist/html2canvas.js/oi/e.exports</<@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:532391\n./node_modules/html2canvas/dist/html2canvas.js/o/a/e.exports/e.exports<@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:365499\n./node_modules/html2canvas/dist/html2canvas.js/o/a/e.exports@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:365604\ni@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:364372\npromise callback*A@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:364508\n./node_modules/html2canvas/dist/html2canvas.js/n/e.exports<@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:364519\nn@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:364315\noi@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:529805\n./node_modules/html2canvas/dist/html2canvas.js/e.exports@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:532716\n./src/worker.js/A.prototype.toCanvas/<@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:28012\nU@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:338040\nF@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:337933\nf@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:335924\n" }
​
columnNumber: 0
​
data: null
​
filename: "https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"
​
lineNumber: 2
​
message: ""
​
name: "NS_ERROR_FAILURE"
​
result: 2147500037
​
stack: "e@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:508673\n./node_modules/html2canvas/dist/html2canvas.js/oi/e.exports</<@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:532391\n./node_modules/html2canvas/dist/html2canvas.js/o/a/e.exports/e.exports<@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:365499\n./node_modules/html2canvas/dist/html2canvas.js/o/a/e.exports@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:365604\ni@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:364372\npromise callback*A@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:364508\n./node_modules/html2canvas/dist/html2canvas.js/n/e.exports<@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:364519\nn@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:364315\noi@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:529805\n./node_modules/html2canvas/dist/html2canvas.js/e.exports@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:532716\n./src/worker.js/A.prototype.toCanvas/<@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:28012\nU@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:338040\nF@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:337933\nf@https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js:2:335924\n"
​
<prototype>: ExceptionPrototype { toString: toString(), name: Getter, message: Getter, … }
index.js:38:15

An alternative is to render the html in server code - e.g. using puppeteer:

"use strict";

const puppeteer = require("puppeteer");

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto("http://localhost:8080/longpage.html", {
    waitUntil: "networkidle2",
  });
  // page.pdf() is currently supported only in headless mode.
  // @see https://bugs.chromium.org/p/chromium/issues/detail?id=753118
  await page.pdf({
    path: "longpage.pdf",
    format: "A4",
    displayHeaderFooter: true,
    timeout: 0,
  });

  await browser.close();
})();
npm i puppeteer
node ./printOnServer.js
stefan.seeland
  • 2,065
  • 2
  • 17
  • 29