Css 幻影不';t使用自定义样式渲染页脚

Css 幻影不';t使用自定义样式渲染页脚,css,header,pdf-generation,footer,phantomjs,Css,Header,Pdf Generation,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 ou

我举了以下例子:

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);
        }
    });
}
但不幸的是,这不起作用。我正在尝试创建pdf文件,如下所示:

./phantomjs rasterize.js index.html test.pdf

根据我过去的经验,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);
    }
});
}
var page=require('webpage')。create(),
系统=要求(“系统”);
if(系统参数长度<3){
log('用法:printheaderfooter.jsURL文件名');
幻影。出口(1);
}否则{
var address=system.args[1];
var输出=system.args[2];
page.viewportSize={宽度:600,高度:600};
页面大小={
格式:“A4”,
边距:“1厘米”,
页脚:{
高度:“1厘米”,
内容:phantom.callback(函数(pageNum,numPages){
返回“页脚”+pageNum+“/”+numPages+”;
})
}
};
第页打开(地址、功能(状态){
如果(状态!=“成功”){
console.log('无法加载地址!');
}否则{
setTimeout(函数(){
页面渲染(输出);
phantom.exit();
}, 200);
}
});
}

注意:您的代码中
边距:“1cm”后缺少逗号。我们知道类不起作用,但内联样式起作用。我们可以做的是用计算样式替换类

下面是一个函数,它将获取一段html,用html在主体中创建一个临时元素,用类计算每个元素的样式,内联添加计算的样式并返回新的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);
}
然后只需在页脚中调用此函数:

page.paperSize = {
    footer: {
        contents: phantom.callback(function(pageNum, numPages) {
            if (pageNum == numPages) {
                return "";
            }
            return replaceClassWithStyle("<h1 class='footer_style'>Footer" + pageNum + " / " + numPages + "</h1>");
        })
    }
};
page.paperSize={
页脚:{
内容:phantom.callback(函数(pageNum,numPages){
如果(pageNum==numPages){
返回“”;
}
返回replaceClassWithStyle(“页脚”+pageNum+“/”+numPages+”);
})
}
};
您需要在
page.open()
中移动所有这些内容

我对它进行了测试,页脚向右对齐。

我对PhantomJS 1.9.7进行了更新

此版本修复了以下问题:

  • 规避父文档为空白的bug(PhantomJS 1.9.7)
  • 嵌套样式时的样式混合(改为深度优先遍历)
  • 当标记没有类时也有效
/**
*将HTML放在父文档中,将CSS样式转换为固定的计算样式声明,然后返回HTML。
*(页眉/页脚是必需的,这些页眉/页脚存在于HTML文档之外,在其他方面很难设置样式)
*/
函数replaceCswithComputedStyle(html){
返回页面。评估(函数(html){
var host=document.createElement('div');
setAttribute('style','display:none;');//由于某种原因,愚蠢的hack或PhantomJS将“清空”主文档
host.innerHTML=html;
//附加以获取父页面的样式
document.body.appendChild(主机);
var elements=host.getElementsByTagName('*');
//以相反的顺序迭代(深度优先),这样样式就不会相互影响
对于(var i=elements.length-1;i>=0;i--){
元素[i].setAttribute('style',window.getComputedStyle(元素[i],null.cssText));
}
//再次从父页面中删除,这样我们就干净了
document.body.removeChild(主机);
返回host.innerHTML;
},html);
}

是的,我知道这个解决方案,但我需要通过使用css类使其工作。这看起来是呈现页眉/页脚的理想解决方案,但在v1.9.7中,这似乎是在appendChild之后“清空”document.body。可能是幻影虫。你用哪个版本测试过这个?
page.paperSize = {
    footer: {
        contents: phantom.callback(function(pageNum, numPages) {
            if (pageNum == numPages) {
                return "";
            }
            return replaceClassWithStyle("<h1 class='footer_style'>Footer" + pageNum + " / " + numPages + "</h1>");
        })
    }
};