之前有个需求,将页面转为pdf,当时使用itext转换,但是呢样式与实际在浏览器中打开的样式存在差异。比如选择项长得不一样,CheckBox长得不一样,这就不行,需求要跟浏览器打开一模一样,后经过多方面查找,终于找到一个靠谱点的解决方案:使用phantomjs插件。
首先下载 phantomjs 插件:
https://download.csdn.net/download/qq_21134557/10643339
这个插件各个版本都有些小bug,我这里使用的是1.9.7。 高版本存在问题是:table中跨列的单元格左侧边框不显示。
低版本能显示,但是也存在问题:table 中跨列的单元格的左侧的单元格高度不正确,如下图:(理论上左侧三行高度应该平均分配)
使用phantomjs :
一、下载后,解压到目录,我这里解压到C盘:(根据项目需求,可放在项目中,然后获取项目根目录来取到文件目录)
二、创建一个js文件:html2pdf.js,我这里放在文件夹phantom下。
内容如下:
var page = require('webpage').create();
var system = require('system');
读取命令行参数,也就是js文件路径。
if (system.args.length === 1) {
console.log('Usage: loadspeed.js <some URL>');
//这行代码很重要。凡是结束必须调用。否则phantomjs不会停止
phantom.exit();
}
page.settings.loadImages = true; //加载图片
page.settings.resourceTimeout = 30000;//超过10秒放弃加载
//截图设置,
//page.viewportSize = {
// width: 1000,
// height: 3000
//};
var address = system.args[1];
page.open(address, function(status) {
function checkReadyState() {//等待加载完成将页面生成pdf
setTimeout(function () {
var readyState = page.evaluate(function () {
return document.readyState;
});
if ("complete" === readyState) {
page.paperSize = { width:'297mm',height:'500mm',orientation: 'portrait',border: '1cm' };
var timestamp = Date.parse(new Date());
var pdfname = 'HT_'+timestamp + Math.floor(Math.random()*1000000);
var outpathstr = "E:/POMFiles/HTPDF/"+pdfname+".pdf";
page.render(outpathstr);
//page.render("c://test.png");
//console.log就是传输回去的内容。
console.log("生成成功");
console.log("$"+outpathstr+"$");
phantom.exit();
} else {
checkReadyState();
}
},1000);
}
checkReadyState();
});
三、Java中调用:
package com.eweaver.base.util;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
* 转换html为pdf
*
* @author xiongfan
*
*/
public class Html2pdf {
public static String parseHtml2Pdf(String url) throws IOException {
System.out.println(url);
//执行phantomjs 生成js
Runtime rt = Runtime.getRuntime();
Process p = rt.exec("C:\\phantom\\bin\\phantomjs.exe C:\\phantom\\html2pdf.js "+url);
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;
}
}
调用 parseHtml2Pdf()方法,就可以将html页面转换为pdf了。路径也可以定义。我这边直接固定写死了。
关于跨行的单元格左侧行高不一致问题,我的解决方法是在页面中加入js代码,自动为跨行所涉及到的tr计算行高,并赋值,这样就解决了,代码就不贴了。