nico
nico

Reputation: 1352

Get page count before printing a web page

I’m trying to automate PDF generation from web pages. My goal is to create single-page PDFs by adjusting print dimensions dynamically.

Currently, I have this working solution that requires manual verification of the page count:

heightMultiplier = 2.5;
document.head
    .appendChild(document.createElement("style"))
    .sheet.insertRule(`@page { size: 21cm ${heightMultiplier * 29.7}cm; }`, 0);
window.print();

This code adjusts the print height to create a single-page PDF by multiplying the standard A4 height (29.7cm) by a factor. The width remains at A4 standard (21cm). I execute it in the browser’s developer console.

What I need is a way to programmatically determine the initial page count that would be shown in the browser’s print dialog. This would allow me to:

  1. Calculate the number of pages before printing
  2. Set the heightMultiplier automatically
  3. Generate the PDF without manual intervention

Is there a way to get this information using JavaScript? I’ve tried looking into the window.print() API but couldn’t find relevant methods.

What I’ve considered

Any suggestions would be appreciated!

Upvotes: 0

Views: 48

Answers (1)

K J
K J

Reputation: 11940

I don't think there is going to be a simple reliable "Fits All" solution because when starting to scale a print such as this page, there is much other dynamic interference.

enter image description here

However if you have a static page this should be a good starting point.

When printing to PDF Chromium's use a "local" fixed "Media" height so for International ISO users that is 803x1132.

<embed id="plugin" type="application/x-google-chrome-pdf" original-url="chrome-untrusted://print/29/0/print.pdf" src="chrome-untrusted://print/29/0/print.pdf" background-color="0xFFE6E6E6" first-page-separator="0" style="position: relative !important; top: 0px; min-height: calc(100% + 0px);" javascript="block" stream_timestamp="undefined" embed-top-offset="0" width="803" height="1132" top-level-url="undefined" pdfdigsigpolicyenabled="" pdfxfaformsenabled="" pdffreetextenabled="" data-docheight="1132" data-docwidth="803">

So to allow for "worst case" aiming for a "single page" we need to round the body down to 1131px by adjusting the scale with zoom. Beware, I have not tested, but suspect if page exceeds the size of 10 x 1131 px (i.e. 10%) it will default to print 11 pages as per the default size?

var body = document.body;
var heightMultiplier = Math.max( body.scrollHeight, body.offsetHeight ) + 10;
{document.body.style.zoom = (113100 / heightMultiplier) + "%" };
window.print();

This ensures that at 100% printing the page body content will fit vertically as within one page high. However there is a lot of white space included. Thus for a given case you need to adjust other page style factors, as you currently do, using <style> injection.

By setting the margins beforehand to 0 and widening some of the divisions we can reduce some of the white space.

enter image description here

Upvotes: 0

Related Questions