【问题标题】:Trying to hide first footer/header on PDF generated with Puppeteer试图隐藏使用 Puppeteer 生成的 PDF 上的第一个页脚/页眉
【发布时间】:2019-08-23 12:57:29
【问题描述】:

我是使用 nodejs 函数和 puppeteer 的新手。以前我使用的是 wkhtmltopdf,但目前它的选项很差。

所以,我的想法是从带有第一个封面的 html 生成 pdf(具有完整 A4 宽度/高度的图像),因为页脚是从 index.js 生成的,所以无法在 FIRST 上隐藏它PDF 页面。

//Imports
const puppeteer = require('puppeteer');
//Open browser
async function startBrowser() {
    const browser = await puppeteer.launch({headless: true, args:['--no-sandbox']});
    const page = await browser.newPage();
    return {browser, page};
}
//Close browser
async function closeBrowser(browser) {
    return browser.close();
}
//Html to pdf
async function html2pdf(url) {
    const {browser, page} = await startBrowser();
    await page.goto(url, {waitUntil: 'networkidle2'});
    await page.emulateMedia('screen');
    //Options
    await page.pdf({
        printBackground: true,
        path: 'result.pdf',
        displayHeaderFooter: true,
        footerTemplate: '<div style="width:100%;text-align:right;position:relative;top:10px;right:10px;"><img width="60px" src="data:data:image/..."'
        margin : {top: '0px',right: '0px',bottom: '40px',left: '0px' },
        scale: 1,
        landscape: false,
        format: 'A4',
        pageRanges: ""
    });
}
//Exec
(async () => {
    await html2pdf('file:///loc/node_pdfs/givenhtml.html');
    process.exit(1);
})();

我的问题是,有没有办法找到第一个页脚并将其隐藏在索引函数中?

谢谢!

【问题讨论】:

标签: node.js pdf puppeteer


【解决方案1】:

目前存在多个错误(请参阅 this question/answerthis one),无法使其正常工作。

目前只有使用此技巧的标头才有可能(取自github comment):

await page.addStyleTag({
    content: `
        body { margin-top: 1cm; }
        @page:first { margin-top: 0; }
    `,
});

这将基本上隐藏第一页上的边距,但在使用底部边距时不起作用(也注意到here)。

可能的解决方案

我推荐的解决方案是创建两个 PDF,一个只有第一页,没有边距,另一个有剩余页面和边距:

await page.pdf({
    displayHeaderFooter: false,
    pageRanges: '1',
    path: 'page1.pdf',
});

await page.pdf({
    displayHeaderFooter: true,
    footerTemplate: '<div style="font-size:5mm;">Your footer text</div>',
    margin: {
        bottom: '10mm'
    },
    pageRanges: '2-', // start this PDF at page 2
    path: 'remaining-pages.pdf',
});

根据您执行任务的频率,您可以手动合并 PDF 或使用 easy-pdf-merge 之类的工具自动合并(我自己没有使用过这个)。

【讨论】:

  • 好吧,看起来操纵边距底部是不可能的,所以第二个解决方案对我来说没问题,因为第一页是静态的。谢谢托马斯!
  • 我正在使用第二种解决方案,它给了我一个错误。协议错误 (Page.printToPDF): 页面范围语法错误 await page.pdf({ format: 'A3', printBackground: true, pageRanges: '2-' }) 在我的情况下,我需要显示页眉和页脚第一页仅不在其他页面上。 @Thomas Dondorf
  • 哦,我得到它是因为我的 pdf 页面长度只有 1,但是如何在运行时确定 pdf 页面数?
【解决方案2】:

小提示:easy-pdf-mergepdf-merge 有一些“系统工具依赖项” 我更喜欢pdf-lib,一个简单的 js 工具,您可以在其中使用 Buffers 和 Typescript 支持

我的打字稿:

import {PDFDocument} from 'pdf-lib'
...

const options: PDFOptions = {
    format: 'A4',
    displayHeaderFooter: true,
    footerTemplate: footerTemplate,
    margin: {
        top: '20mm',
        bottom: '20mm',
    },
}
const page1: Buffer = await page.pdf({
    ...options,
    headerTemplate: '<div><!-- no header hack --></div>',
    pageRanges: '1',
})
const page2: Buffer = await page.pdf({
    ...options,
    headerTemplate: headerTemplate,
    pageRanges: '2-',
})

const pdfDoc = await PDFDocument.create()

const coverDoc = await PDFDocument.load(page1)
const [coverPage] = await pdfDoc.copyPages(coverDoc, [0])
pdfDoc.addPage(coverPage)

const mainDoc = await PDFDocument.load(page2)
for (let i = 0; i < mainDoc.getPageCount(); i++) {
    const [aMainPage] = await pdfDoc.copyPages(mainDoc, [i])
    pdfDoc.addPage(aMainPage)
}

const pdfBytes = await pdfDoc.save()

// Buffer for https response in my case
return Buffer.from(pdfBytes)
...

【讨论】:

    猜你喜欢
    • 2019-10-28
    • 2018-12-28
    • 1970-01-01
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-17
    相关资源
    最近更新 更多