调用无头浏览器根据option生成echart的图片,主要用于系统后台任务生辰报表(PDF、word)格式
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import org.xml.sax.SAXException;
import com.esafenet.ta.common.paramconfig.ParamConfig;
import com.esafenet.ta.util.StringUtil;
import com.github.abel533.echarts.Option;
import com.google.gson.Gson;
import com.sun.jna.Platform;
public class PhantomjsRender {
// 如果要更换运行环境,请注意exePath最后的phantom.exe需要更改。因为这个只能在window版本上运行。前面的路径名
// 也需要和exePath里面的保持一致。否则无法调用
// private static String projectPath = System.getProperty("user.dir");
// private static String jsPath = "../webapps/ta-server/jsp/da/auditReport/js/phantomjsrender.js"; //web项目找tomcat下的js
//phantomjs的exe文件路径
// private static String exePath ="E:/phantomjs/phantomjs-2.1.1-windows/phantomjs-2.1.1-windows/bin/phantomjs.exe";
public static void main(String[] args) throws IOException, SAXException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
// 测试调用。传入url即可
// String html = getParseredHtml2("http://localhost:8080/ta-server/auditreport/phanttomjsRender.pub");
// CreatReportService cs = new CreatReportService();
// Option option = cs.getPieOptionByOneDimensional();
Class<?> cla=Class.forName("com.esafenet.ta.da.auditreport.utils.CreatReportService");//根据类的全路径进行类加载,返回该类的Class对象
Object realClass= cla.newInstance();//产生这个Class类对象的一个实例,调用该类无参的构造方法,作用等同于new TestOne()
Method realtmethod = cla.getMethod("getPieOptionByOneDimensional");
@SuppressWarnings("unused")
Option option = (Option) realtmethod.invoke(realClass);
// String html = getParseredHtml2("about:blank",option);
// System.out.println("html: " + html);
}
/**
* 将option渲染成图片返回存放路径
* @param url
* @param option
* @return
* @throws IOException
*/
@SuppressWarnings("static-access")
public String getParseredHtml2(String url,Option option) throws IOException {
String exePath = ParamConfig.getInstance().getValue("da.report.phantomjs.path", "E:/phantomjs/phantomjs-2.1.1-windows/phantomjs-2.1.1-windows/bin/phantomjs.exe");
System.out.println("在linux下执行无头浏览器时获取的phantomjs的路径"+exePath);
// /E:/apache7/webapps/ta-ser+ver/jsp/da/auditReport/js/phantomjsrender.js
String jsPath = ParamConfig.class.getResource("/").getPath().replace("WEB-INF/classes/", "") + "jsp/da/auditReport/js/phantomjsrender.js";
System.out.println("在linux下执行无头浏览器时获取的phantomjsrender的路径"+jsPath);
if(Platform.isWindows()){
jsPath = jsPath.replaceFirst("/", "");
}
// jsPath = "../webapps/ta-server/jsp/da/auditReport/js/phantomjsrender.js"; //web项目找tomcat下的js
// jsPath="E:/apache7/webapps/ta-server/jsp/da/auditReport/js/phantomjsrender.js";
Runtime rt = Runtime.getRuntime();
option.animation(false);
Gson gson = new Gson();
String json = gson.toJson(option);
// String json = JSON.toJSONString(option);
// json=json.replaceAll("\"", "\"sb110");
System.out.println(json);
Date date= new Date();
String wqjson = String.valueOf(date.getTime());
StringUtil stringUtil = new StringUtil();
json = stringUtil.toBase64StringNoWrap(json.getBytes("UTF-8"));
// Base64 JAVA后台编码与JS前台解码(解决中文乱码问题)
// http://blog.youkuaiyun.com/z798083517/article/details/74642781
// json = java.net.URLEncoder.encode(json, "UTF-8");
System.out.println(json);
Process p = rt.exec(exePath + " " + jsPath + " " + url+ " " + json + " " + wqjson);
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);
}
br.close();
is.close();
return sbf.toString();
}
// private String base64Encode(String str) throws Exception {
// if (str != null) {
// String os = System.getProperty("os.name");
// if (os.toLowerCase().startsWith("windows")) {
// str = str.replaceAll("\\r\\n", "<br/>");
// } else if (os.toLowerCase().startsWith("linux")) {
// str = str.replaceAll("\\n", "<br/>");
// }
// return new String(Base64.encodeBase64(str.getBytes("GBK")));
// }
// return null;
// }
}
以下代码为无头浏览器调用的js代码
var page = require('webpage').create();
var system = require('system');
var url;
// phantom.outputEncoding="gb2312";
phantom.outputEncoding="utf-8";
page.onConsoleMessage = function(msg) {
console.log(msg);
};
//phantom没有界面,所以也就不能处理alert窗口,但可以通过此接口捕获到alert。
page.onAlert = function(msg) {
console.log('ALERT: ' + msg);
};
if (system.args.length === 1) {
console.log("zhuijia canshu");
phantom.exit(1);
} else {
url = system.args[1];
// data = 'title=expanding&name=42';
data = 'json='+system.args[2]+'&name='+system.args[3];
page.open(url,function(status) { // page.open(url, 'post', data,function(status) {
page.injectJs('jquery.js');
page.injectJs('echarts-all.js');
if ( status === "success" ) {
// console.log("Page load ok");
// console.log($.parseJSON(system.args[2]));
var option = system.args[2];
var msg = page.evaluate(function(option) {
$(document.body).css('backgroundColor', 'white');
$(document.body).append("<div id='main' style='height:100%;width:100%;'></div>");
// $(document.body).append("<textarea id='echartOption' rows='30' cols='150' ></textarea>");
var myChart = echarts.init(document.getElementById('main'));
// option = {
// animation:false,
// title : {
// text: '某站点用户访问来源',
// subtext: '纯属虚构',
// x:'center'
// },
// tooltip : {
// trigger: 'item',
// formatter: "{a} <br/>{b} : {c} ({d}%)"
// },
// legend: {
// orient : 'vertical',
// x : 'left',
// data:['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
// },
// toolbox: {
// show : true,
// feature : {
// mark : {show: true},
// dataView : {show: true, readOnly: false},
// magicType : {
// show: true,
// type: ['pie', 'funnel'],
// option: {
// funnel: {
// x: '25%',
// width: '50%',
// funnelAlign: 'left',
// max: 1548
// }
// }
// },
// restore : {show: true},
// saveAsImage : {show: true}
// }
// },
// calculable : true,
// series : [
// {
// name:'访问来源',
// type:'pie',
// radius : '55%',
// center: ['50%', '60%'],
// data:[
// {value:335, name:'直接访问'},
// {value:310, name:'邮件营销'},
// {value:234, name:'联盟广告'},
// {value:135, name:'视频广告'},
// {value:1548, name:'搜索引擎'}
// ]
// }
// ]
// };
function Base64() {
// private property
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
// public method for encoding
this.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
// public method for decoding
this.decode = function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
// private method for UTF-8 encoding
_utf8_encode = function (string) {
string = string.replace(/\r\n/g,"\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}
// private method for UTF-8 decoding
_utf8_decode = function (utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while ( i < utftext.length ) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++;
} else if((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
} else {
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
}
var b = new Base64();
option = b.decode(option);
// document.getElementById('main').innerHTML= option;
// option = '{"color":["rgb(51, 51, 51)"],"calculable":true,"animation":false,"toolbox":{"feature":{"mark":{"show":true,"title":{"markUndo":"删除辅助线","markClear":"清空辅助线","mark":"辅助线开关"},"lineStyle":{"color":"#1e90ff","type":"dashed","width":2}},"magicType":{"show":true,"title":{"bar":"柱形图切换","stack":"堆积","tiled":"平铺","line":"折线图切换"},"type":["bar","line","stack","tiled"]},"restore":{"show":true,"title":"还原"},"saveAsImage":{"show":true,"title":"保存为图片","type":"png","lang":["点击保存"]}},"orient":"vertical","show":true,"x":"right","y":"center"},"tooltip":{"trigger":"axis","axisPointer":{"type":"shadow"}},"legend":{"data":["数量"],"padding":20},"xAxis":[{"type":"category","axisLabel":{"interval":0,"rotate":15},"data":["小黑2","蓝胖2","斧王2","幻影2","王强2"]}],"yAxis":[{"type":"value"}],"series":[{"name":"数量","type":"bar","data":["25","25","25","25","3"]}]}';
myChart.setOption(JSON.parse(option));
// myChart.setOption(JSON.parse(option.replace(/sb110/g,'"')),true);//$.parseJSON(option)
// $("#echartOption").val(myChart.getDataURL("png"));
// return myChart.getDataURL("png");
},option);
page.render("esafenet/images/pdfechart"+system.args[3]+".png");
// console.log(page.title);
// var sss = page.content;
console.log("esafenet/images/pdfechart"+system.args[3]+".png");
} else {
console.log("Page failed to load.");
}
phantom.exit(0);
});
}
//Example using HTTP POST operation post提交
// "use strict";
// var page = require('webpage').create(),
// server = 'http://posttestserver.com/post.php?dump',
// data = 'universe=expanding&answer=42';
//
// page.open(server, 'post', data, function (status) {
// if (status !== 'success') {
// console.log('Unable to post!');
// } else {
// console.log(page.content);
// }
// phantom.exit();
// });
//Example using HTTP POST operation post提交传json
// "use strict";
// var page = require('webpage').create(),
// server = 'http://posttestserver.com/post.php?dump',
// data = '{"universe": "expanding", "answer": 42}';
//
// var headers = {
// "Content-Type": "application/json"
// }
//
// page.open(server, 'post', data, headers, function (status) {
// if (status !== 'success') {
// console.log('Unable to post!');
// } else {
// console.log(page.content);
// }
// phantom.exit();
// });
//输出信息
// page.onResourceRequested = function (req) {
// console.log('requested: ' + JSON.stringify(req, undefined, 4));
// };
//
//page.onResourceReceived = function (res) {
//console.log('received: ' + JSON.stringify(res, undefined, 4));
// };
//var s = helloworldService.sayHello("wwww");
//console.log(s);
//将page转存为图片
// page.render("D:/test/wwqq.html");
//将page转存为pdf
// page.paperSize = { format: 'A4',
// orientation: 'portrait',
// border: '1cm' };
// page.render("wwqq.pdf");
// 下面为无效代码,测试用的
// var content = page.evaluate(function () {
// var element = document.getElementsByTagName('html');
// return element.textContent;
// });
// console.log(content);