注意:对于有ajax异步数据的网页转PDF,需要等到页面所有ajax请求完毕再作PDF转换
使用npm全局安装phantomjs(没有npm的需要先安装nodejs)
npm install -g phantomjs
效果预览
生成PDF代码
/**
* 注意: phantomjs不支持es6语法
*/
// 引入必要的模块
var webPage = require('webpage');
var system = require('system');
var width = 842, height = width * 297 / 210;
var params = {}, extraParamsArr = [];
// 接收通过运行时的命令传递过来的参数,存储到extraParamsArr对象中
if (system.args.length < 4) {
var args = system.args;
for (var i = 1; i < args.length; i++) {
var param = args[i].split('=');
params[param[0]] = param[1];
if (['company', 'path'].indexOf(param[0]) === -1) {
extraParamsArr.push(args[i]);
}
}
}
var page = webPage.create();
// 设置视窗大小
page.viewportSize = {width: width, height: height};
// requests,responses用以保存请求,响应的数量及状态
var requests = {};
var responses = {};
// 监听请求
page.onResourceRequested = function (r) {
requests[r.id] = ({id: r.id, url: r.url, status: 'pending'});
};
// 监听响应
page.onResourceReceived = function (r) {
responses[r.id] = ({id: r.id, url: r.url, status: r.status});
};
// 监听超时的响应
page.onResourceTimeout = function (r) {
responses[r.id] = ({id: r.id, url: r.url, status: 'timeout'});
};
// 设置允许图片加载,浏览器标识
page.settings.loadImages = true;
page.settings.userAgent = 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36';
// PDF 分页设置
page.paperSize = {
format: 'A4',
width: width,
height: height,
margin: 0,
header: {
height: 50,
contents: phantom.callback(function (pageNum, numPages) {
return "<div style='width: 100%;box-sizing: border-box;'>\
<div style='width: 60%; float: left;'>\
<div>监控周期</div>\
<div>2019/02/04 - 2019/03/04</div>\
</div>\
<div style='width: 38%;text-align: right;float: left;'>\
RiskRaider\
风险雷达\
</div>\
</div>";
})
},
footer: {
height: 50,
contents: phantom.callback(function (pageNum, numPages) {
if (pageNum == 1) {
return '';
}
return "<span style='float:right;margin-right: 40px'><b>" + pageNum + " / " + numPages + "</b></span>";
})
}
};
// 生成PDF
function waitOrRender(second) {
window.setTimeout(function () {
var requestsNum = Object.keys(requests).length;
var responsesNum = Object.keys(responses).length;
if (page.loading) {
console.log('页面已加载' + page.loadingProgress + '%');
waitOrRender(1);
} else if (requestsNum > 0 && requestsNum === responsesNum) {
window.setTimeout(function () {
// 请求和响应数量一致,说明所有请求都已返回
if (Object.keys(requests).length === Object.keys(responses).length) {
console.log('页面请求返回完毕', 'PDF文件制作中,请稍后...');
var timestamp = new Date().getTime();
page.render(params.company + '_' + params.path + '_' + timestamp + '.pdf', {
format: 'pdf',
quality: '100'
});
console.log('PDF生成完毕,退出程序');
phantom.exit();
} else {
waitOrRender(2);
}
}, 2000);
} else {
console.log(responsesNum + '/' + requestsNum);
waitOrRender(2);
}
}, second * 1000);
}
var baseUrl = 'http://*********/#/' + params.path + '?company=' + encodeURIComponent(params.company);
var url = baseUrl + '&' + extraParamsArr.join('&');
console.log(url);
page.open(url, function (status) {
if (status !== 'success') {
console.log('Unable to load!');
phantom.exit();
} else {
console.log('Hello phantomJs !');
waitOrRender(1);
}
});