I’m working on generating a PDF from HTML using Puppeteer. The HTML contains tables, and I need to ensure that when a table breaks across pages, the new page starts with a padding of 140px. (because i dont want it to clash with my fixed header)
The script runs without errors, but the padding is not added to the new pages where tables break across pages. The new pages start immediately without the required 140px padding.
-
HTML Structure:
Here is my
products_template.html (this is the layout of my table)
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Products</title>
<style>
body {
margin: 0;
box-sizing: border-box;
font-size: 10pt;
position: relative;
}
.content-wrapper {
padding-top: 140px;
}
.products {
margin-bottom: 50px;
padding: 0 20mm;
margin-top: 20px;
}
.products table {
width: 100%;
border-collapse: collapse;
border: 2px solid #00BCE4;
border-bottom: none;
page-break-inside: avoid;
}
.products th, .products td {
padding: 8px;
border-left: none;
border-right: none;
}
.products tr {
border-bottom: 1px solid rgba(66,66,66, 0.2);
}
.products th, .products td {
padding: 10px;
}
.products tr:first-child th, .products tr:first-child td {
border-top: none;
border-bottom: none;
}
.line {
width: 100%;
height: 10px;
background-color: #007BA7;
}
.header-image img {
width: 60px;
height: auto;
}
.header-container {
padding: 10px 0;
display: flex;
justify-content: space-between;
margin: 20px 0;
align-items: center;
padding: 0 20mm;
}
.header-content p {
font-size: 10pt;
}
.header-content {
display: flex;
gap: 24px;
}
.header {
justify-content: space-between;
align-items: center;
width: 100%;
position: fixed;
top: 0;
left: 0;
}
.thin-line {
margin: 0 20mm;
height: 1px;
background-color: rgba(66,66,66, 0.2);
}
.footer {
position: fixed;
bottom: 0;
width: 100%;
height: 10px;
background-color: #007BA7;
}
.category-header {
background-color: #00BCE4;
color: white;
font-size: 14pt;
padding: 8px;
font-family: 'montserrat', sans-serif;
padding: 20px;
text-transform: uppercase;
}
.total-header, .total-price {
color: #00BCE4;
font-size: 14pt;
font-family: 'montserrat', sans-serif;
}
.product-name {
width: 500px;
}
.total-container {
display: flex;
justify-content: space-between;
padding: 20px;
border: 2px solid #00BCE4;
margin-bottom: 18px;
}
.product-unit {
text-align: right;
}
.page-break {
page-break-before: always;
padding-top: 140px;
}
</style>
</head>
<body>
<div class="content-wrapper">
<div class="products">
{% for category, products in categories.items() %}
<table class="product-table">
<thead>
<tr>
<th class="category-header" colspan="3">{{ category }}</th>
</tr>
</thead>
<tbody>
{% set ns = namespace(category_total=0) %}
{% for product in products %}
{% set product_total = product.quantity * product.price %}
{% set ns.category_total = ns.category_total + product_total %}
<tr>
<td class="product-name">{{ product.name }}</td>
<td class="product-quantity" style="text-align: right;">{{ product.quantity }}</td>
<td class="product-unit">{{ product.entity }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="total-container">
<div class="total-header"><strong>Totaal</strong></div>
<div class="total-price"><strong>€{{ '%.2f' % ns.category_total }}</strong></div>
</div>
<div class="page-break"></div>
{% endfor %}
</div>
</div>
<div class="footer"></div>
</body>
</html>
-
Puppeteer Script:
Here is my
generate_pdf.js
script:const puppeteer = require('puppeteer'); const fs = require('fs'); async function generatePDF(htmlFilePath, outputPdfPath) { const browser = await puppeteer.launch(); const page = await browser.newPage(); const htmlContent = fs.readFileSync(htmlFilePath, 'utf8'); await page.setContent(htmlContent, { waitUntil: 'networkidle0' }); await page.pdf({ path: outputPdfPath, format: 'A4', printBackground: true, margin: { top: '0mm', right: '0mm', bottom: '0mm', left: '0mm' }, preferCSSPageSize: true, }); await browser.close(); } const args = process.argv.slice(2); const htmlFilePath = args[0]; const outputPdfPath = args[1]; generatePDF(htmlFilePath, outputPdfPath).catch(console.error);