0

This is my html

<body>
<div>
    <span>Information:</span><br><span>aaaaa</span>
    <div id="printhead">
        <p>
            This is the print page header
        </p>
    </div>
    </div>
    <div id="docbody" >
       <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
        <p>aaaaaaaaaa</p>
    </div>

    <div class="footer">
        <p class="left">this is a footer   Page </p>
        <p class="right"></p>
    </div>
</body>

css

 /* not working*/
        @page {

                    margin-bottom: 40px;
                    counter-increment: page;
                    content: "Page " counter(page) " of " counter(pages);

            @bottom-right  {
                border-top: 1px solid #000000;
                padding-right: 20px;
                font-size: 12px !important;

            }
            @bottom-left  {
                content: "Footer content goes here.";
                border-top: 1px solid #000000;
            }

            }

            div#printhead {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 2em;
                text-align: center;
                padding-bottom: 1em;
                border-bottom: 1px solid;
                margin-bottom: 10px;
            }

            div#printhead {
                display: block;
                clear: both;
                text-align: center;
            }

            div#docbody {
                margin-top: 3em;
                overflow: visible !important;
                overflow-wrap: break-word;
                page-break-after: auto;
                height: 50px;
            }

            body {
                display: flex;
                flex-direction: column;
                min-height: 100vh;
            }

            .footer {
                width: 100%;
                display: flex;
                margin-top: auto;
                justify-content: space-between;
                bottom: 0px;
                font-size: 12px;
                position: fixed;
            }

            .left {
                width: 15%;
            }

            .footer:after 

{
            counter-increment: page;
            content: counter(page);
            font-size: 12px;

        }

I tried to add a header, footer and number of page while printing the html. The header will overlap content on next page, same for footer. And also, i have some information need placed top left of the header but it only show on first page. For the number of page, it is not working. It always show page 1 for every printed pages.

The format look like this http://www.basoftware.com.my/wp-content/uploads/2016/01/yearly-purchase-1.png

Any solution to fix this problem? Thanks in advance.

Crazy
  • 757
  • 11
  • 30

1 Answers1

0

Client browser / ctrl+p

The answer is probably this is impossible. You were probably looking at the w3 spec or quackit which show a way to add content to margin boxes, and even have page numbering. While that is fantastic, if you look at the top of the w3 spec you see this disappointing line:

W3C Working Draft, 18 October 2018

As far as I can tell it's not supported by anything. My testing supports that as well as this wiki page.

I saw a hack (which someone pointed out in the comments on OP) that some said would work that looks like this:

#footer:after {
    position: fixed;
    bottom: 0in;
    counter-increment: page;
    content: "Page " counter(page);
}

While this almost works, it has a couple problems for me. In chromium/electron it seems that for PDF gen it doesn't actually "increment" except to 1, so my page number doesn't increase, and additionally it seems that if the content has a negative margin putting it into the page margin, it will be drawn on the next page, rather than on the page margin. So I'm not sure how we would be-able to allot space for the fixed item anyway in the pdf.

You may have also seen something like this:

@media print {
    #footer {
        display: block;
        position: running(header);
    }
    @page { @top-center { content: element(header, last-except) }}
}

That also doesn't have browser support, though this spec sounds older, but presumably not "done" anyway: W3C Working Draft, 13 May 2014

Server Side

If you're interested in configuring this for chromium when creating a PDF server side, there is chromium support for header and footer snippets. So if you're using the right tools, you may have access to that for things like generating PDFs on a server.

Puppeteer is the best option I found for that. Below is an example written for node.js using the node package.

const puppeteer = require('puppeteer');

(async() => {
    // Launch browser, and open tab
    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    // Load html, you can use anything you could put in a URL bar
    await page.goto('file:///C:/filepath/page.html');

    // Create pdf
    await page.pdf({
        path: 'output.pdf',
        format: 'A4',
        displayHeaderFooter: true,
        headerTemplate: '<div></div>',
        footerTemplate: 
            '<div style="font-size: 12px; width: 100%; text-align: center; font-style: italic; padding-bottom: 0.5in; font-family: serif;">'+
                'Page <span class="pageNumber"></span>'+
            '</div>',
        margin: {
            top: '0.5in',
            bottom: '1.5in',
            left: '1in',
            right: '1in',
        }
    });

    // Close browser, now that we're done
    await browser.close();
})();

Note it's important that you specify the font size for the header/footer content, as for me it seemed to be defaulting to like 1px or something, and I could barely see anything, and thought it was just a weird line before I added that.

There may be unofficial ports for other languages (C#), and obviously you could write a command line interface in node, or configure it to take web requests to generate the pdf that could be called in any language.

csga5000
  • 3,616
  • 4
  • 35
  • 49