Reputation: 481
When I used the puppeteer to print html to pdf, I met a strange problem. I find the puppeteer always ignore some CSS rules which is in @media print.
Here is my env:
Puppeteer version: 1.11
Platform / OS version: Win10/CentOS7
Node.js version: 10.15.0
CSS codes:
@media print {
.flipbook-viewport .flipbook{
width: 794px!important;
height: 1123px!important;
max-height: 1123px;
max-width: 794px;
background-color: red;
}
.right-01 .image {
width: 92%;
background-repeat: no-repeat;
background-size: 100%;
background-image: url('../image/content/test.png');
height: 920px;
/* width: 740px; */
margin-top: 0.8rem;
}
}
You can notice that I set a background-color to check the test result. In my test, when I executed puppeteer with page.emulateMedia('print'), the flipbook-viewport and flipbook's rules work fine. But the right-01 and image's didn't work.
But the funny thing is when I used the @media screen (also change the page.emulateMedia to screen) with the same rules, they all worked fine. So I think it might have some problem with puppeteer.
What is the expected result? good.pdf
What happens instead? wrong.pdf
Does anyone meet this problem before? How to resolve this problem? Please help.
An example of my puppeteer code:
const puppeteer = require('puppeteer-core');
(async () => {
const browser = await puppeteer.launch({executablePath:'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'});
const page = await browser.newPage();
await page.goto('http://www.kaol.org/TurnPage/', {waitUntil: 'networkidle2'});
await page.emulateMedia('print');
await page.pdf({path: 'hn.pdf', format: 'A4', printBackground: true});
await browser.close();
})();
Upvotes: 9
Views: 27232
Reputation: 74076
The documentation for PDF print of puppeteer list a few possible options. Among them also printBackground
:
<boolean>
Print background graphics. Defaults to false.
Try setting this to true
to include background-graphics and -colors to your PDF-export.
Upvotes: 11
Reputation: 1033
For me none of the solutions I found on stackoverflow worked, I almost "lost hope". But after playing around with all the info I found it turned out that you need only 2 things:
printBackground
option has to be set to TRUE, e.g.:
page.pdf({ path: "./my.pdf", printBackground: true });
!important
, e.g.:p {
color: red !important;
background: blue !important;
}
That's it.
P.S. I have currently Puppeteer v5.5.0.
Upvotes: 3
Reputation: 2434
From what I can tell, Puppeteer uses the screen dimensions of your machine to determine the width and height to first generate the page and then print that page to PDF, so the machine's display values are used when background-size: 100%
are used.
Ýou can pass the dimensions explicitly:
@media print {
@page {
size: A4 portrait;
margin: 0;
}
}
And to your body
add the size in paper dimension sizes so they aren't derived from the system:
background-size: 21cm 29.7cm;
Then pass the preferCSSPageSize
and printBackground
flags:
const pdf = await page.pdf({
preferCSSPageSize: true,
printBackground: true
});
It also seems format: 'A4'
at best does nothing when your @page
has dimensions and at worst possibly overrides part of your css, so I'd leave it out entirely.
Upvotes: 7
Reputation: 16856
puppeteer
is just a library to drive Chrome/Chromium, so if anything goes wrong while using it, our best bet is to open Chromium with puppeteer.launch({headless:false})
and debug there. (However printing to PDF is not supported in headful mode now, so we may just use a full browser)
There's a built-in support for debugging print mode in Chrome DevTools, here's how to turn it on.
Having turned that on, after page reload I saw a 404 in the network tab: that background image could not be found. It happened because when you had moved @media print out of stylesheet into the main page, the relative link ../image/content/20181206picture1.png
became broken (before it was relative to stylesheet location but now it is relative to the page location).
So after fixing this link here's the resulting pdf which I believe is correct. Can't comment on width/height though, there could be something else in your stylesheets affecting that.
Upvotes: 1