Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

puppeteer header and footertemplate doesnt work

Tags:

css

pdf

puppeteer

This is my code for creating the pdf. Everything works great except the footer and header doesn't work. They are there (i think) but not visible. I have tried with displayHeaderFooter: true but all that makes is a date stamp in the header and some broken html code in the footer (as last picture).

async function createListenPdf(html, header, footer) {
try {
    var jobId = uuidv4();

    this.browser = await puppeteer.launch();
    const page = await browser.newPage();
    var viewport = {
        width:1165,
        height:1200
    }
    page.setViewport(viewport);
    page.on("console", msg => {
        for (let i = 0; i < msg.args.length; ++i) {
            console.log(`${jobId} - From page. Arg ${i}: ${msg.args[i]}`);
        }
    });

    await page.goto(`data:text/html,${html}`, { waitUntil: 'networkidle0' });   

    await page.emulateMedia('screen');

    console.log("Header footer");
    var buffer = await page.pdf({
         printBackground: true,         
         footerTemplate: "<div style='width: 200px; background-color: #4286f4; position: relative; position: absolute; top:0;'>Hej</div>",
         headerTemplate: "<div style='width: 200px; background-color: #4286f4; position: relative; position: absolute; bottom: 0;'>Footer</div>",
         //displayHeaderFooter: true, 
         margin:{
             top: "100px",
             bottom: "100px"
         }
    });

    console.log(`${jobId} - Done. Will return the stream`);
    return buffer;
}
finally {
    if (this.browser) {
        console.log(`${jobId} - Closing browser`);
        this.browser.close();
    }
}
 }

enter image description here

As you can see i somehow got a footer with some grey area (i don't know why its grey). When i enable displayHeaderFooter: true in the options it looks like this:

enter image description here

Has anyone managed to create a pdf with puppeteer using html with header and footer? Here in their API description its seems pretty obvious but it really doesn't work.

https://github.com/GoogleChrome/puppeteer/blob/v1.3.0/docs/api.md

like image 603
Daniel Gustafsson Avatar asked Apr 20 '18 14:04

Daniel Gustafsson


3 Answers

Just bumped into the issue.

My observations about headerTemplate/footerTemplate are the following:

  1. At least the font-size has to be specified (it's set to 1px by default, which is very small):
headerTemplate: '<span style="font-size: 10px"> <span class="pageNumber"></span>/<span class="totalPages"></span></span>',
  1. top/bottom margin must be defined to set space for the header/footer

  2. Some CSS properties indeed don't work. I didn't have any success with background-color, but maybe it's because the background isn't painted for these sections.

  3. No asynchronous code (that would require an HTTP request) is allowed, such as calling a CSS stylesheet, loading an image or a font.
    Consequently, CSS have to be inlined. To add an image, it can be base-64 encoded, as shown below. Concerning the fonts, we would need to rely on what is expected to be installed on the Puppeteer server I guess. Maybe there's a way to also embed it in base-64, I didn't try.

const printPDF = async () => {
    const footer = `<footer style="margin: auto; width: 40%">
            <img style="float: left; marginRight: 8px; marginLeft: 36px; width: 25%" src="data:image/jpeg;base64,/9j/4AAQSkZJRgAB...09Yv//Z" alt="Pivohub" />
            <p style="font-family: arial; float: right; width: 55%; color: red; margin-top: 24px; font-size: 10px">
                <b>My footer</b>
            </p>
        </footer>`

    const content = `<!DOCTYPE html>
        <html>
            <head>
                <meta charSet="utf-8"/>
                <style type="text/css">
                    body { backgroundColor: "red" }
                </style>
            </head>
            <body>
                <h1>Hello</h1>
            </body>
        </html>`

    const browser = await puppeteer.launch({ headless: true })
    const page = await browser.newPage()
    await page.setContent(content, { waitUntil: "networkidle0" })
    const buffer = await page.pdf({
        format: "A4",
        displayHeaderFooter: true,
        headerTemplate: '<span style="font-size: 10px"> <span class="pageNumber"></span> of <span class="totalPages"></span></span>',
        footerTemplate: footer,
        margin: { top: "100px", bottom: "200px" },
        printBackground: true,
    })
}

In this sample, the base 64 image was truncated. An image can be converted thanks to an online base-64 converter such as https://www.base64-image.de.

like image 163
arvymetal Avatar answered Nov 12 '22 23:11

arvymetal


Please try the following templates:

headerTemplate: '<span style="font-size: 30px; width: 200px; height: 200px; background-color: black; color: white; margin: 20px;">Header 1</span>',
footerTemplate: '<span style="font-size: 30px; width: 50px; height: 50px; background-color: red; color:black; margin: 20px;">Footer</span>'

Not all styling properties are supported, you should avoid using position, top, bottom.

Also make sure you are on the latest version of puppeteer.

like image 17
Tarun Lalwani Avatar answered Nov 12 '22 23:11

Tarun Lalwani


  // or a .pdf file
  await page.pdf({
    printBackground: true,
    width: `595px`, // ? 3508 x 2480 (print) || 595 pixels x 842 pixels (screen)
    height: `842px`, // ? Here subraction for making alignment looks cool
    margin: {
      top: '25px',
      bottom: '60px',
      left: '25px',
      right: '25px'
    },
    path: path.join(ROOT_PATH, 'pdf', 'report.pdf'),
    displayHeaderFooter: true,
    footerTemplate: `
    <p style="margin: auto;font-size: 13px;">
      <span class="pageNumber"></span>
        /
      <span class="totalPages"></span>
    </p>
    `
  });

Hopefully, this one resolved someone's issue with the same problem. The footer was not shown before properly and finally done about a little bit search so comes with the above solution.

NOTE:

  1. Don't forget to mentioned margin-bottom: 60px(atleast).
  2. Same for displayHeaderFooter: true.
  3. Must needs to specify the font-size: 10px(atleast bcze default by font-size: 0).

For more info refer to this issue: https://github.com/puppeteer/puppeteer/issues/1822

like image 5
Mohamed Jakkariya Avatar answered Nov 12 '22 23:11

Mohamed Jakkariya