Phantomjs不会使用自定义样式呈现页脚

Eri*_*rik 8 css pdf-generation header footer phantomjs

我有以下示例:

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);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我使用看起来像我的css文件中的footer_style类:

.footer_style {
  text-align:right;
}
Run Code Online (Sandbox Code Playgroud)

但不幸的是,这不行.我正在尝试创建如下的pdf文件:

./phantomjs rasterize.js index.html test.pdf
Run Code Online (Sandbox Code Playgroud)

mak*_*mak 9

我们知道类不起作用,但内联样式可以.我们可以做的是用计算的样式替换类.

这是一个函数,它将获取一段html,使用html在body中创建一个临时元素,使用类计算每个元素的样式,添加计算样式内联并返回新的html.

function replaceClassWithStyle(html) {
    return page.evaluate(function(html) {
        var host = document.createElement('div');
        host.innerHTML = html;
        document.body.appendChild(host); // if not appended, values will be blank
        var elements = host.getElementsByTagName('*');
        for (var i in elements) {
            if (elements[i].className) {
                elements[i].setAttribute('style', window.getComputedStyle(elements[i], null).cssText);
            }
        }
        document.body.removeChild(host);
        return host.innerHTML;
    }, html);
}
Run Code Online (Sandbox Code Playgroud)

然后只需在页脚中调用此函数:

page.paperSize = {
    footer: {
        contents: phantom.callback(function(pageNum, numPages) {
            if (pageNum == numPages) {
                return "";
            }
            return replaceClassWithStyle("<h1 class='footer_style'>Footer" + pageNum + " / " + numPages + "</h1>");
        })
    }
};
Run Code Online (Sandbox Code Playgroud)

你需要把所有这些都移到里面page.open().

我测试了它,页脚与右边对齐.

  • 修正了问题^和其他一些问题:http://stackoverflow.com/a/27296129/678265 (2认同)

Daa*_*hof 5

我对mak 对 PhantomJS 1.9.7 的优秀答案进行了更新。

该版本修复了:

  • 规避父文档“空白”的错误(PhantomJS 1.9.7)
  • 样式嵌套时的样式混合(改为深度优先遍历)
  • 当标签没有类时也适用
/**
 * 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);
}
Run Code Online (Sandbox Code Playgroud)


Cyb*_*axs 3

根据我过去的经验,phantomjs 不支持自定义页眉/页脚中的样式。

我发现的唯一解决方案是应用像这样的内联样式:

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) {
            return "<h1 style='text-align:right'>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);
    }
});
}
Run Code Online (Sandbox Code Playgroud)

注意:您的代码中缺少逗号margin: "1cm"