Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Puppeteer pdf page break bug

I try to generate pdf file by puppetter. It works good for one page but when I try to generate multipage pdf document, I have a bug with page breaks. HTML template is used for generate below. Please, help me if you can. Pre condition for reproduce: fill first page on 100% height and add title for block below.

HTML template

function getHTMLTemplate(
    height = 'auto', 
    component = '<div></div>', 
    style = '<style></style>',
    header = '<div></div>',
    footer = '<div></div>',
) {
    return `
        <!DOCTYPE html>
        <html>                
            <head>
                <meta charset="utf-8" />
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
                <title>HTML to PDF Example</title>
                <meta name="viewport" content="width=device-width, initial-scale=1">
                <style>
                    * {margin: 0; padding: 0; border-spacing: 0;}

                    .page {
                        width: 210mm;
                        height: ${height};
                        overflow: hidden;
                        background: transparent;
                        margin-top: -1px !important;
                        margin-bottom: -1px !important;
                    }

                    body>div {
                        width: 100%;
                        position: fixed;
                    }

                    body>div:first-child {
                        top: 0;
                    }

                    body>div:nth-child(2) {
                        bottom: 0;
                    }
                    
                    @page {
                        size: 'A4';
                        margin: 0;
                    }
                    
                    @media print {
                        thead {display: table-header-group;} 
                        tfoot {display: table-footer-group;}

                        html, body {
                            width: 210mm;
                            height: 297mm;
                        }
                        
                        tbody::after {
                            content: ''; 
                            display: block;
                            page-break-after: always;
                            page-break-inside: avoid;
                            page-break-before: avoid;        
                        }
                    }

                    .block {
                        top: 0;
                        width: 210mm;
                        height: 40px;
                        position: absolute;
                        background: #092a4e;
                        z-index: 1;
                    }
                </style>
            </head>
            <body>
                <div class="block"></div>
                ${header}
                ${footer}
                <table>
                    <thead>
                        <tr>
                            <td>
                                ${header}
                            </td>
                        </tr>
                    </thead>
                    <tbody>
                        <tr>
                            <td>
                                <div class="page">
                                    ${component}
                                    ${style}
                                </div>
                            </td>
                        </tr>
                    </tbody>
                    <tfoot>
                        <tr>
                            <td>
                                ${footer}
                            </td>
                        </tr>
                    </tfoot>
                </table>
            </body>
        </html>
    `;
}

Generate PDF

const browser = await puppeteer.launch({ args: ['--no-sandbox', '--disable-setuid-sandbox'] });
const page = await browser.newPage();
await page.emulateMediaType('print');
await page.setContent(utils.getHTMLTemplate(`calc(891mm - 82px)`, component, sheet.getStyleTags(), template.header, template.footer));
const buffer = await page.pdf({
   format: "A4",
   margin: { top: 0, bottom: 0, right: 0, left: 0 },
   printBackground: true,
});

Bug enter image description here

like image 574
Vladyslav Shpytalnyi Avatar asked Dec 18 '22 11:12

Vladyslav Shpytalnyi


1 Answers

To avoid a div breaking into two pages, add a class (eg. "myDiv") to the div in html and include the below code in page CSS.

@media print {
  .myDiv {
     break-inside: avoid;
  }
}
like image 146
Pankaj Tanwar Avatar answered Dec 19 '22 23:12

Pankaj Tanwar