Kaol
Kaol

Reputation: 481

Puppeteer ignores some CSS rules to print PDF when I used the @media print

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

Answers (4)

Sirko
Sirko

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

nostop
nostop

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:

  1. the printBackground option has to be set to TRUE, e.g.: page.pdf({ path: "./my.pdf", printBackground: true });
  2. add to your background or color values !important, e.g.:
p {
  color: red !important; 
  background: blue !important; 
}

That's it.

P.S. I have currently Puppeteer v5.5.0.

Upvotes: 3

G_V
G_V

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

Vaviloff
Vaviloff

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

Related Questions