Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Phantomjs doesn't render footers with a custom styles

I have the following example:

var page = require('webpage').create(),
    system = require('system');

if (system.args.length < 3) {
    console.log('Usage: printheaderfooter.js URL filename');
    phantom.exit(1);
} else {
    var address = system.args[1];
    var output = system.args[2];
    page.viewportSize = { width: 600, height: 600 };
    page.paperSize = {
        format: 'A4',
        margin: "1cm"
        footer: {
            height: "1cm",
            contents: phantom.callback(function(pageNum, numPages) {
                if (pageNum == numPages) {
                    return "";
                }
                return "<h1 class='footer_style'>Footer" + pageNum + " / " + numPages + "</h1>";
            })
        }
    };
    page.open(address, function (status) {
        if (status !== 'success') {
            console.log('Unable to load the address!');
        } else {                
            window.setTimeout(function () {
                page.render(output);
                phantom.exit();
            }, 200);
        }
    });
}

In the example above I use footer_style class that look likes in my css file the following:

.footer_style {
  text-align:right;
}

But unfortunately that dosen't works. I'm trying to create pdf file such as follows:

./phantomjs rasterize.js index.html test.pdf
like image 319
Erik Avatar asked Jul 06 '13 11:07

Erik


1 Answers

I have an update to mak's excellent answer for PhantomJS 1.9.7.

This version fixes:

  • Circumvent bug which 'blank's the parent document (PhantomJS 1.9.7)
  • Style mixups when styles are nested (do depth-first traversal instead)
  • Also works when tags do not have classes
/**
 * Place HTML in the parent document, convert CSS styles to fixed computed style declarations, and return HTML.
 * (required for headers/footers, which exist outside of the HTML document, and have trouble getting styling otherwise)
 */
function replaceCssWithComputedStyle(html) {
  return page.evaluate(function(html) {
    var host = document.createElement('div');
    host.setAttribute('style', 'display:none;'); // Silly hack, or PhantomJS will 'blank' the main document for some reason
    host.innerHTML = html;

    // Append to get styling of parent page
    document.body.appendChild(host);

    var elements = host.getElementsByTagName('*');
    // Iterate in reverse order (depth first) so that styles do not impact eachother
    for (var i = elements.length - 1; i >= 0; i--) {
      elements[i].setAttribute('style', window.getComputedStyle(elements[i], null).cssText);
    }

    // Remove from parent page again, so we're clean
    document.body.removeChild(host);
    return host.innerHTML;
  }, html);
}
like image 65
Daan Broekhof Avatar answered Sep 30 '22 10:09

Daan Broekhof