参考:https://blog.csdn.net/qq_21134557/article/details/82350686
1、下载phantomjs,配置环境变量
2、编写js文件放到该目录
3、 html2pdf.js 文件
var page = require('webpage').create(),
system = require('system'),
address, output, size;
page.viewportSize = {
width: 2400,
height: 20000
};
page.paperSize = {
format: 'A4', //A4 纸张
orientation: 'portrait',
margin: '0.8cm'
};
page.zoomFactor = 1;//放大比例
page.settings.loadImages = true;
page.settings.userAgent = 'Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Safari/537.36';
console.log("000" + system.args[0]);
console.log("111" + system.args[1]);
console.log("222" + system.args[2]);
if (system.args.length < 3 || system.args.length > 5) {
console.log('Usage: rasterize.js URL filename');
phantom.exit(1);
} else {
address = system.args[1];
output = system.args[2];
console.log(page.settings.userAgent );
// 不加分页的话,只输出一页pdf,底部会有大量空白。
//google "phantomjs render pdf bottom blank" 可以看到别人也报过这种bug
// 最终查找Phantomjs generates multiple page PDF 竟然解决了问题
page.paperSize = { format: 'A4', orientation: 'portrait', margin: '0.8cm' };
// page.viewportSize = { width: 600, height: 800 };
console.log("open page now");
page.open(address, function (status) {
console.log(status);
//evaluate注册一个回调函数,页面加载完就执行。用来操作页面中的DOM元素
//修改微信公众号文章中图片lazy load的方式
var size = page.evaluate(function () {
//此函数在目标页面执行的,上下文环境非本phantomjs,所以不能用到这个js中其他变量
//这个控制台打印的效果在phantomjs执行界面看不到
console.log('start image lazy loading');
var imgs = document.getElementsByTagName('img');
var size = 0;
console.log(size);
for (var i = imgs.length - 1; i >= 0; i--) {
var data_src = imgs[i].getAttribute("data-src");
if (data_src){
imgs[i].setAttribute("src", data_src);
size++;
}
}
return size;
} );
console.log("change lazy load img number:" + size);
// 预留一定的渲染时间
window.setTimeout(function () {
var timestamp = Date.parse(new Date());
var pdfname = 'HT_'+timestamp + Math.floor(Math.random()*1000000);
var outpathstr = "D:/POMFiles/HTPDF/"+output+".pdf";
page.render(outpathstr);
page.close();
console.log('render ok');
phantom.exit();
}, 10000);
});
};
// phantom.exit();
4、打开cmd运行指令:
三个参数的位置
示例地址命令:
phantomjs .\html2pdf.js 'https://www.baidu.com/' 'D:/naiba/222.pdf'
第一个参数为加载的js文件
第二个参数为网页地址
第三个地址为pdf生成的输出目录
重点:
String cmd = "F:\\htmlpdf\\phantomjs\\bin\\phantomjs.exe F:\\htmlpdf\\phantomjs\\bin\\html2pdf.js www.baidu.com filenameAbc";
命令行与java代码里执行的不一样,命令行可以有单引号不影响,java代码有单引号报错
错误示例:
String cmd = "F:\\htmlpdf\\phantomjs\\bin\\phantomjs.exe F:\\htmlpdf\\phantomjs\\bin\\html2pdf.js ’www.baidu.com‘ ‘filenameAbc’";
5、完整的java调用,重点cmd命令行写法
public static String parseHtml2Pdf(String url,String fileName) throws IOException {
fileName = fileName.replace(" ","_");
fileName = fileName.replace("-","_");
fileName = fileName.replace(":","_");
//执行phantomjs 生成js
Runtime rt = Runtime.getRuntime();
// url = "https://www.csdn.net/?spm=1011.2124.3001.4476";
String cmd = "F:\\htmlpdf\\phantomjs\\bin\\phantomjs.exe F:\\htmlpdf\\phantomjs\\bin\\html2pdf.js "+url+" " + fileName;
System.out.println(cmd);
Process p = rt.exec(cmd);
InputStream is = p.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuffer sbf = new StringBuffer();
String tmp = "";
while ((tmp = br.readLine()) != null) {
sbf.append(tmp);
}
String resultstr = sbf.toString();
String[] arr = resultstr.split("\\$");
String result = "";
for(String s : arr){
if(s.endsWith("pdf"))result = s;
}
return result;
}
接下来图片加载有问题,有一些没有加载出来,更换js。
到此,已经可以生成pdf了。