Add content to the bottom of the last page
Asked Answered
J

3

22

I am using wkhtmltopdf to create PDF reports from HTML, I need to create a custom report that follows this pattern:

  1. Some information at the top of the first page.
  2. A table that can have 1 to n rows (it should use any amount of pages it needs)
  3. Some information at the end of the last page.

Putting all this together does the trick; however because step 3 info appears immediately after the table, is there a way to put the content at the end of the page?

I am not even sure if this solution is CSS based or wkhtmltopdf based.

Jackstay answered 3/2, 2012 at 20:31 Comment(0)
S
43

http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html

Take a look at "Footers And Headers" section.

You can use --footer-html combined with some JavaScript to do this.

wkhtmltopdf --footer-html footer.html http://www.stackoverflow.com/ so.pdf

I based the contents of my footer.html on the example provided in the link above:

<!DOCTYPE html>

<script>
window.onload = function() {
    var vars = {};
    var x = document.location.search.substring(1).split('&');
    for (var i in x) {
        var z = x[i].split('=', 2);
        vars[z[0]] = unescape(z[1]);
    }

    //if current page number == last page number
    if (vars['page'] == vars['topage']) {
        document.querySelectorAll('.extra')[0].textContent = 'extra text here';
    }
};
</script>

<style>
.extra {
    color: red;
}
</style>

<div class="extra"></div>
Scleroma answered 9/2, 2012 at 2:55 Comment(1)
Thanks, I had a lot of problems because I hadn't QT patched version, spent a lot of time compiling without success until I realized there was a binary version in the page.Jackstay
B
4

This a quite difficult task and I don't think you can solve this with pure CSS at this time (though I would love to be proven wrong).

Also the support for determined page breaks (page-break-inside: avoid;) isn't the best. In fact I don't think it works with table so far. You probably would end up with some rows split around the pagebrake. (Webkit renders one PDF and then cuts it into single pages, mostly regardless whats on the edge...)

enter image description here

My solution to this dilemma was to create single placeholder divs in the size of a single page and then distribute the content with some programming langugae between these placeholders before generating the PDF.

In the last of such wrappers you could then add an absolute positioned footer at the bottom.

Here is some sample code:

<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <meta charset="UTF-8">
    <title>Sample Data</title>
    <style>

        * {
            padding: 0;
            margin: 0;
        }   

        .page {
            page-break-inside: avoid;
            height: 1360px;

            position: relative;
        }

        table {
            border-collapse: collapse;
            width: 100%;
        }

        td {
            border: 1px solid #ccc;
            padding: .23em;
        }

        .footer {
            position: absolute;
            color: red;
            bottom: 0;
        }

    </style>
</head>
<body>

<div class="page one">

    <p>
        Some info Here... at the top of first page
    </p>

    <!-- Zen Coding: table>tbody>(tr>td>{A sample table}+td>{Foo bar})*42 -->       

    <table>
        <tbody>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
        </tbody>
    </table>    
</div>

<div class="page two">
    <table>
        <tbody>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
            <tr><td>A sample table</td><td>Foo bar</td></tr>
        </tbody>
    </table>

    <p class="footer">
        The last info here in the bottom of last page
    </p>
</div>

</body>
</html>
Blew answered 7/2, 2012 at 21:43 Comment(3)
It seems like an interesting idea, how ever this is how wkhtmltopdf converts it dl.dropbox.com/u/1990697/out.pdf of course I am open to a javascript solution in case of being necessary.Jackstay
@Jackstay You probably need to fiddle around a bit with the height (.page{height: 1360px;}) for the page container. On my machine it works with my sample code.Blew
@Jackstay your attachment not availableEisenhart
V
-1

I’m having a little trouble following what you mean. What’s the difference between the content being “immediately after the table” and “at the end of the table”?

The tfoot element might be what you’re looking for:

<table>
    <thead>
        <tr><th>Header</th></tr>
    </thead>
    <tfoot>
        <tr><th>Footer</th></tr>
    </tfoot>
    <tbody>
        <tr><td>Data</td></tr>
        <tr><td>Data</td></tr>
        <tr><td>Data</td></tr>
    </tbody>
</table>

If not, could you elaborate? A short example of the HTML you have or pictures of what it looks like and what you want it to look like might help.

Volscian answered 7/2, 2012 at 16:42 Comment(1)
There was a typo error, I mean to show at the "last of the page" instead "last of the table" this is an example: dl.dropbox.com/u/1990697/example.pdfJackstay

© 2022 - 2024 — McMap. All rights reserved.