关于分页符,如何让 Puppeteer PDF 生成与 HTML 文档完全匹配?

bad*_*der 8 javascript css google-chrome node.js puppeteer

我正在使用 Puppeteer 生成 PDF 文件,使用静态 HTML 作为源:

const page = await browser.newPage();
await page.setContent(html); //html is read in from the file system

const pdf = await page.pdf({
    format: 'A4',
    printBackground: true,
    preferCSSPageSize: true
});
Run Code Online (Sandbox Code Playgroud)

同样的 HTML 也会显示给我的应用程序的前端用户,因此他们可以在下载 PDF 之前准确预览内容。

为了匹配一张 A4 纸的大小,我使用 CSS<body>将 HTML的标签设置为特定的宽度和高度,在此过程中考虑页边距。

例如,我的 CSS 可能如下所示:

@page {
    margin: 1cm; //tells Puppeteer to print the PDF with a 1cm margin
}

body {
    width: 19cm; // (21cm width minus 1cm margin on each side)
    height: 27.7cm // (29.7cm height minus 1cm margin top and bottom)
}
Run Code Online (Sandbox Code Playgroud)

我面临的问题是关于分页符;Puppeteer 有时会将底部内容拆分为单独的页面。

例如,对于前端用户看到的 A4 页面表示的底部,这就是 HTML 的样子。

在此处输入图片说明

正如您所看到的,底部一行文本显然有足够的空间来容纳,它没有被截断。

但是,Puppeteer 像这样打印 PDF:

在此处输入图片说明

即它将文本分成两个单独的页面。

这种行为似乎也很不稳定;我有时注意到(例如使用不同的文本/段落长度),它不会将内容拆分为单独的页面。

你知道 Puppeteer 为什么要拆分文本吗?我已经阅读了文档,但似乎找不到任何解决方案。

谢谢!

Men*_*los 8

问题在于页面大小的 CSS 设置与 chrome 用于打印的 A4 页面大小不匹配。

查看以下问题/答案,特别是已批准答案中的 CSS 设置。

CSS设置A4纸张大小

建议的解决方案是同时利用印刷媒体规则

他们有一个特定的演示,代码如下:

@page {
  size: A4;
  margin: 0;
}
@media print {
  html, body {
    width: 210mm;
    height: 297mm;
  }
  /* ... the rest of the rules ... */
}
Run Code Online (Sandbox Code Playgroud)

我稍微修改了他们的演示,以包含您的 Lorem Ipsum 项目符号文本。您可以查看@http: //jsfiddle.net/x7s2cntj/1/

单击“运行”查看结果,或使用 headless chrome 在 headless chrome 中尝试puppeteer

我从堆栈溢出中删除了该代码片段,因为代码片段窗口内似乎应用了一些额外的 CSS。