【问题标题】:Puppeteer ignores some CSS rules to print PDF when I used the @media print当我使用@media print 时,Puppeteer 忽略了一些 CSS 规则来打印 PDF
【发布时间】:2019-05-30 19:27:48
【问题描述】:

当我使用 puppeteer 将 html 打印为 pdf 时,我遇到了一个奇怪的问题。我发现木偶师总是忽略 @media print 中的一些 CSS 规则。

这是我的环境:

Puppeteer 版本:1.11
平台/操作系统版本:Win10/CentOS7
Node.js 版本:10.15.0

CSS 代码:

@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;
    }
}

您可以注意到我设置了背景颜色来检查测试结果。在我的测试中,当我使用 page.emulateMedia('print') 执行 puppeteer 时,翻书视口和翻书的规则工作正常。但是 right-01 和 image 不起作用。

但有趣的是,当我以相同的规则使用@media 屏幕(也将 page.emulateMedia 更改为屏幕)时,它们都运行良好。所以我觉得puppeteer可能有问题。

预期的结果是什么? good.pdf

反而会发生什么? wrong.pdf

以前有人遇到过这个问题吗?如何解决这个问题?请帮忙。

我的 puppeteer 代码示例:

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();
})();

【问题讨论】:

  • 我过去看到过类似的行为并且有一个想法...但是您可以在此页面的某个地方托管以运行测试吗?
  • @Vaviloff,当然可以使用this link来测试。现在,我通过设置min-width: 1600px来使用@media screen来暂时解决这个问题。
  • 嘿,太好了,你能发布你的 puppeteer 代码的最小示例吗? — 因为我不知道您使用哪些打印仿真设置。
  • @Vaviloff,我更新了我的代码示例。我想使用@media print 设置来控制打印样式。但它不起作用。我期待着您亲切的答复。谢谢。
  • 你解决了吗?我对图像有这样的问题。

标签: puppeteer


【解决方案1】:

puppeteer 的documentation for PDF print 列出了一些可能的选项。其中还有printBackground

<boolean> 打印背景图形。默认为 false。

尝试将其设置为 true 以在 PDF 导出中包含背景图形和颜色。

【讨论】:

  • 谢谢。但我已经将printBackground 设置为true。您可以查看我转换的 pdf 文件。颜色和图形都很好。问题是图片大小不合适。
【解决方案2】:

据我所知,Puppeteer 使用您机器的屏幕尺寸来确定宽度和高度以首先生成页面,然后将该页面打印为 PDF,因此在使用 background-size: 100% 时使用机器的显示值。

你可以显式传递维度:

@media print {
    @page {
        size: A4 portrait;
        margin: 0;
    }
}

在您的body 中添加纸张尺寸大小的尺寸,这样它们就不会来自系统:

background-size: 21cm 29.7cm;

然后传递preferCSSPageSizeprintBackground 标志:

const pdf = await page.pdf({
    preferCSSPageSize: true,
    printBackground: true
});

当您的@page 具有尺寸并且最坏的情况可能会覆盖您的 css 的一部分时,format: 'A4' 充其量似乎什么也不做,所以我会完全忽略它。

【讨论】:

    【解决方案3】:

    对我来说,我在 stackoverflow 上找到的任何解决方案都不起作用,我几乎“失去了希望”。但是在玩弄了所有信息之后,我发现你只需要两件事:

    1. printBackground 选项必须设置为 TRUE,例如: page.pdf({ path: "./my.pdf", printBackground: true });
    2. 添加到您的背景或颜色值!important,例如:
    p {
      color: red !important; 
      background: blue !important; 
    }
    
    

    就是这样。

    附:我目前有 Puppeteer v5.5.0。

    【讨论】:

    • !important + printBackground 就像一个魅力。我建议的唯一小改进是仅为打印选项添加重要规则,例如,如果您使用 scss。 @media print { p { color: red !important; } }
    【解决方案4】:

    puppeteer 只是一个驱动 Chrome/Chromium 的库,所以如果在使用它时出现任何问题,我们最好的办法是使用 puppeteer.launch({headless:false}) 打开 Chromium 并在那里调试。 (不过现在headful模式不支持打印到PDF,所以我们可以使用完整的浏览器)

    Chrome DevTools 中内置了对调试打印模式的支持,here's how to turn it on

    打开它后,重新加载页面后,我在网络选项卡中看到一个 404:找不到 background image。发生这种情况是因为当您将 @media print out of 样式表移到主页时,相对链接 ../image/content/20181206picture1.png 被破坏(之前它是相对于样式表位置,但现在它是相对于页面位置)。

    所以在修复此链接here's the resulting pdf 之后,我认为这是正确的。虽然无法评论宽度/高度,但您的样式表中可能有其他东西会影响它。

    【讨论】:

    • 谢谢。我知道背景图像损坏的问题。关键是我想让网页内容在打印时填满整个 A4 页面(查看这篇文章中的 good.pdf)。所以我尝试使用@Media print来控制它。
    猜你喜欢
    • 2019-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 2010-12-13
    相关资源
    最近更新 更多