How can I change paper size in headless Chrome --print-to-pdf

Viewed 22587

I am using headless Chrome to export html documents to pdf

google-chrome --headless --disable-gpu --print-to-pdf='output_path' 'url'

How can I change paper size in generated pdf?

I have control on both Chrome parameters and html.

I always get US Letter.

There are no documented command-line options for this.

I've tried setting CSS: @page {size: A4;}. No effect in headless mode, but works when I hit Ctrl+P in normal mode (option to choose paper size for Save as pdf disappears, exported pdf has A4 page size).

I've tried this on Chrome versions 59, 60 and 61 on Ubuntu 16.04.

5 Answers

The page size could be set in inches/mm. I haven't tested with a size in pixels. Here is a set of CSS rules which did the trick for me:

@page {
  margin: 0;
  padding: 0;
  size: 5in 6.5in;
}

My exact case is rendering svg-to-pdf, not html; For svg, you may also need to add width and height attributes to <svg> tag:

<svg width="5in" height="6.5in" ...>

That's all! Output PDF won't have margins, and will preserve the desired size - 5"x6.5" in my case.

Page size apparently can now be "almost" accurately controlled without using the debug interface.

The following is a method of creating a PDF with nearly the exact dimensions of its contents using headless chrome.

<head>
    <style>
      html, body {
        width:  fit-content;
        height: fit-content;
        margin:  0px;
        padding: 0px;
      }
     </style>

     <style id=page_style>
      @page { size: 100px 100px ; margin : 0px }
     </style>

</head>

This prepares for making the pdf to fit the page, but will not be right, since the page size has been set to an arbitrary value of 100x100.

After the document has been rendered, the following is used to set the page size correctly at the bottom of the page:

<script>
window.onload(fixpage);

function fixpage() {

     renderBlock = document.getElementsByTagName("html")[0];
     renderBlockInfo = window.getComputedStyle(renderBlock)

     // fix chrome page bug
     fixHeight = parseInt(renderBlockInfo.height) + 1 + "px"   

     pageCss = `@page { size: \${renderBlockInfo.width} \${fixHeight} ; margin:0;}`
     document.getElementById("page_style").innerHTML = pageCss
}
</script>

This approach eliminates the header/footer and deals with a numerical issue with pixel conversion to pdf.

One more thing

Chrome currently has a bug with the calculation of absolute height of a div when you use the CSS

line-height: normal; 

This will make the page calculation too short and lead to an extra pdf page being generated. You can fix this using:

line-height: unset; 

Throughout your CSS. You won't get an accurate height without it!

Related