Printing Headers and Footers with Puppeteer: A Comprehensive Guide
Printing web pages with Puppeteer's page.pdf()
API is a breeze, but what if you want to add custom headers and footers to your printed documents? This is where things get a bit more complex. While Puppeteer doesn't directly support header and footer customization within the page.pdf()
function, we can achieve this using clever workarounds.
The Problem:
The page.pdf()
function doesn't offer any built-in options for adding headers and footers.
Simplified Explanation:
Imagine you're printing a report. You want a company logo and the report's title to appear on each page, and the page number at the bottom. This is where the need for headers and footers arises.
Let's Get Practical:
Let's start with a basic example of how to print a page using Puppeteer:
const puppeteer = require('puppeteer');
async function printPDF() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://www.example.com');
await page.pdf({ path: 'example.pdf' });
await browser.close();
}
printPDF();
The Missing Piece:
This code will successfully generate a PDF, but it lacks headers and footers. Now, let's explore how we can add them.
Methods for Implementing Headers and Footers:
-
Using CSS and HTML:
- The Idea: The most flexible approach involves crafting a dedicated HTML template for the header and footer, then injecting it into the page's DOM using Javascript before printing.
- Implementation:
async function printPDF() { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://www.example.com'); await page.evaluate(() => { // Injecting the HTML into the body document.body.innerHTML = ` <header> <h1>My Header</h1> </header> <main> ${document.body.innerHTML} </main> <footer> <p>Page <span id="pageNumber"></span> of <span id="totalPages"></span></p> </footer> `; // Setting up page number logic document.getElementById('pageNumber').textContent = 1; document.getElementById('totalPages').textContent = 1; }); await page.pdf({ path: 'example.pdf', printBackground: true, displayHeaderFooter: true, format: 'Letter', // Or any other format you need margin: { top: "2cm", right: "2cm", bottom: "2cm", left: "2cm" } // Set margins as desired }); await browser.close(); } printPDF();
- Explanation:
- We inject HTML into the page's body to create header and footer sections.
- The content of the original page is wrapped within a
main
tag. - We utilize JavaScript to handle page numbering.
- Benefits: This method provides exceptional control over the look and feel of headers and footers, allowing for complex layouts and dynamic content.
-
Using Puppeteer's Print Options:
- The Idea: The
page.pdf()
function offers certain options for customizing the printing process. Although they don't provide the granular control of CSS and HTML, we can use them to create simple headers and footers. - Implementation:
async function printPDF() { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://www.example.com'); await page.pdf({ path: 'example.pdf', printBackground: true, displayHeaderFooter: true, headerTemplate: '<div style="font-size: 12px; text-align: center;">My Header</div>', footerTemplate: '<div style="font-size: 10px; text-align: center;">Page <span class="pageNumber"></span></div>', format: 'Letter', // Or any other format you need margin: { top: "2cm", right: "2cm", bottom: "2cm", left: "2cm" } // Set margins as desired }); await browser.close(); } printPDF();
- Explanation:
- We leverage
headerTemplate
andfooterTemplate
properties to define simple header and footer content. - This approach works well for basic text-based headers and footers.
- We leverage
- Limitations: This method is less flexible than the CSS/HTML approach and may not suit complex layouts.
- The Idea: The
Choosing the Right Approach:
- For basic headers and footers: Use the
headerTemplate
andfooterTemplate
options. - For advanced customization: Opt for the CSS/HTML injection method.
Important Considerations:
- Page Numbering: Use JavaScript to implement accurate page numbering when printing.
- Margins: Set appropriate margins in your PDF options to ensure proper placement of headers and footers.
- Styling: Use CSS to style your headers and footers according to your preferences.
Example of a Complex Header/Footer:
await page.evaluate(() => {
document.body.innerHTML = `
<header>
<div style="display: flex; justify-content: space-between; align-items: center;">
<img src="https://www.example.com/logo.png" alt="Company Logo" width="100" height="50">
<h1>My Report</h1>
<span>Date: ${new Date().toLocaleDateString()}</span>
</div>
</header>
<main>
${document.body.innerHTML}
</main>
<footer>
<p style="text-align: center;">Page <span id="pageNumber"></span> of <span id="totalPages"></span></p>
</footer>
`;
// ... page number logic
});
Conclusion:
With these techniques, you can easily add elegant headers and footers to your PDF documents generated by Puppeteer. Remember to choose the method that best suits your needs and embrace the power of CSS and HTML for complex designs.
Resources: