如何使用Chrome DevTools协议的printToPDF修改第一页Number或在页眉或页脚模板中执行JS

use*_*380 7 html javascript pdf-generation google-chrome-devtools google-chrome-headless

我正在使用Headless Chrome通过printToPDF CDP方法打印出PDF文件。如果将displayHeaderFooter参数设置为true,则可以使用参数headerTemplate和设置特定的页面页眉和页脚footerTemplate。该协议提供了一些HTML类来显示一些信息,这些是:datetitleurlpageNumbertotalPages

例如,我们可以设置footerTemplate<span class="pageNumber"></span>在页脚中显示当前页码。我们还需要添加一些样式以正确显示它。默认的页眉和页脚设置可以在此处找到,渲染器C ++组件在此处

我想修改显示的pageNumber值。我的目标是从给定的数字开始计算页面数。

木偶API文档注意到headerTemplatefooterTemplate标记具有以下限制:

  1. 模板内的脚本标签不进行评估。
  2. 页面样式在模板内不可见。

一个GitHub的评论提供以下功能:

<div style="font-size: 10px;">
  <div id="test">header test</div>
  <img src='http://www.chromium.org/_/rsrc/1438879449147/config/customLogo.gif?revision=3' onload='document.getElementById("test").style.color = "green";this.parentNode.removeChild(this);'/>
</div>
Run Code Online (Sandbox Code Playgroud)

它说,如果我们onloadimg标签上使用属性,则可以在模板中运行JavaScript。但是,我无法重现结果,该片段显示在屏幕快照中。

例如,以下JavaScript可以计算10页中的页面:

<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" alt="tmpimg" 
onload="var x = document.getElementById('pn').innerHTML; var y = 10; document.getElementById('pn').innerHTML = parseInt(x) + y; this.parentNode.removeChild(this);"/>
<span id="pn" class="pageNumber"></span>
Run Code Online (Sandbox Code Playgroud)

但是很遗憾,该脚本不会修改页码,因此我不知道如何解决此问题。我也曾尝试使用纯CSS解决方案,但没有成功。

欢迎任何想法来解决此问题。

The*_*tan 1

我尝试了直接的方法来解决这个问题,但没有成功。即使像 CSS 表达式和计数器这样晦涩的 api 也无法解决这个问题。幸运的是,似乎有一个足够简单的解决方法。

我们使用pageRange参数单独打印每个页面,然后合并所有页面以生成所需的pdf。这使我们能够打印每个页眉/页脚(如果它是pageNumber. 例如:

const footerTemplate = function (pageNumber) {
    return `<div>Page number: ${pageNumber + 24}</div>`;
};
Run Code Online (Sandbox Code Playgroud)

我们需要遍历每一页并打印它。

const printPage = function (pageNumber) {
    return {
        ...
        path: `html-page-${pageNumber}.pdf`,
        footerTemplate: footerTemplate(pageNumber),
        pageRanges: String(pageNumber)
    };
};


(async function () {
    ...
    const page = await browser.newPage();
    var pageNumber = 1;
    try {
        while (pageNumber > 0) {
            await page.pdf(printPage(pageNumber));
            pageNumber += 1;
        }
    } catch (e) {
    } finally {
       // Merge and clean up
    }
})();
Run Code Online (Sandbox Code Playgroud)

没有简单的方法可以确定要打印的总页数。所以我们不知道什么时候停止。幸运的是,当我们尝试打印超出范围的页面时,Chrome 会发送错误。所以我们可以用它来停止打印。

下面附上一个页码偏移 24 的工作示例。使用依赖项运行:fspdf-merger-jspuppeteer

const footerTemplate = function (pageNumber) {
    return `<div>Page number: ${pageNumber + 24}</div>`;
};
Run Code Online (Sandbox Code Playgroud)