Reputation: 2405
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.
Upvotes: 39
Views: 31353
Reputation: 11736
In all the previous answers I do not see the critical designer words PRINT & MEDIA since PDF page is controlled by a /MediaBox thus regional browser standard letter USA = [0 0 612 792] and others ISO A4 = [0 0 595 842].
In HTML/XHTML printing this is controlled by CSS @Media Print
as seen here, where used for exec Chrome-Headless-Shell --print-to-pdf='output_path' 'url'
from https:// or file://name.xhtml (.ePub) to PDF.
<meta content="width=1610.26, height=1923.75" name="viewport"/>
<style>
@media print { @page { margin: 0; size: 1612px 1924px ; } body { margin: 0; } }
whatever {
...
SIDE NOTE the answer is that WEB px (1/96) will convert to 75% (72/96) as PDF pt (1/72) Thus to get /MediaBox [0 0 1000 600]
use width 1333.33px (A CSS oddity because pixels should only be unitary integers) and height 800px (or use PDF point .floats).
Upvotes: 0
Reputation: 123
I managed to get it correct using org.openqa.selenium.print.PageSize
PrintsPage printer = (PrintsPage) browser;
PrintOptions printOptions = new PrintOptions();
printOptions.setPageSize(new PageSize(21,29.7)); //A4
printOptions.setOrientation(PrintOptions.Orientation.PORTRAIT);
printOptions.setPageRanges("All");
Pdf pdf = printer.print(printOptions);
String content = pdf.getContent();
FileOutputStream fos = new FileOutputStream("C:\\workspace\\tmp\\test.pdf");
byte[] decoder = Base64.getDecoder().decode(content);
fos.write(decoder);
fos.close();
Upvotes: 0
Reputation: 428
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.
Upvotes: 12
Reputation: 651
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!
Upvotes: 6
Reputation: 257
Note: after going through the comments in atomrc's answer, I thought about adding this as an answer to be more clear.
You can't change the page size right now unless using the devtools protocol.
This is a bug in headless Chrome. The @page size
CSS rule is not understood correctly in headless mode, as this user describes it well on the chromium bug tracker:
Desktop Chrome does support @page at-rules for size and margins, and will set the sheet dimensions according to the size property.
It appears that Headless Chrome does parse @page as well to some extent, but behaves differently than the desktop version: If you specify @page {size}, headless seems to change the dimensions of the page box (essentially, the print area), and not the sheet, which always remains US Letter sized. However, it does rotate the sheet if you specify {size: landscape}.
Upvotes: 3
Reputation: 2583
There was a patch created sometime ago that enables page sizing configuration https://codereview.chromium.org/2829973002/
It is now closed and available in the unstable version of chrome, so you can use it as you suggested @page { size: A4 }
.
I tested, it works on the unstable build I have installed (Google Chrome 61.0.3141.7 dev
). I am not sure, though, how to check when it will be available in the stable build ...
Upvotes: 3
Reputation: 329
You can run headless chrome from Node environment.
Then you would be able to pass additional parameters to printToPdf
function including pageWidth
and pageHeight
.
Upvotes: 7