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)
我们知道类不起作用,但内联样式可以.我们可以做的是用计算的样式替换类.
这是一个函数,它将获取一段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().
我测试了它,页脚与右边对齐.
我对mak 对 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)
根据我过去的经验,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"