highchart+table 结合phantomjs 一并生成图片

其实是看到群里有小伙伴有这个需求,我才制作了这个DEMO,因为之前用phantomjs实现过纯后台导出图片,所以顺便改了下以前的DEMO分享给大家。
phantomjs 纯后台导出 请参考:http://www.peng8.net/2014/07/21/render-charts-serverside/

准备工作

  1. 去官网下载最新的phantomjs,官网提供三个版本下载,我电脑是window 7,所以用的是windows版,至于其他系统的请下载对应的版本。
  2. 解压文件,只需要对应的处理文件,例如windows版本里的就要 phantomjs.exerasterize.jsrasterize.js 用来向 phantomjs 发起请求生成快照

前端整理

  • 这里我们需要2个页面,一个页面用来专门显示图表(default),一个用来触发弹出图表(index)
    为什么我们需要2个页面呢?因为这里我们是用到了phantomjs的一个功能,生成快照!所以需要一个干净的页面,只有图表,图片生成的内容也就是我们想要生成最后样子的图片。
  • 我借用了lhgdialog 弹窗插件来弹出展现我们要生成的图表
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
var tips;
var dg;
function openWin() {
dg = $.dialog({
title: 'highchart export by peng8',
content: 'url:Default.aspx',
width: '600px',
button: [
{
id: 'export',
name: '导出图片',
callback: function () {
tips = $.dialog.tips('正在生成图片中,请稍后...', 1000, 'loading.gif');
this.button({ id: 'export', name: '正在生成图片中,请稍后...', disabled: true });
exportImage();
return false;
},
focus: true
},
{
name: '关闭'
}
]
});
}
function exportImage() {
$.ajax({
type: "POST",
url: "Default.aspx?action=export",
data: "url=http://localhost:32423/Default.aspx",
success: function (msg) {
tips.close();
$.dialog({ title:'提示',content: '生成完毕,路径地址:<br />' + msg, lock: true, parent: dg, min: false, max: false });
dg.button({ id: 'export', name: '导出图片', disabled: false });
}
});
}
  • 分析:Default.aspx 是我图表渲染的页面。Default.aspx?action=export 这个请求是ajax post到后台调用phantomjs.exe 生成图片. ajax data里的参数url 是图表渲染页面即Default.aspx(注意:这里这个路径一定要带上http,也就是访问这个地址能打开图表

服务端代码

  • default.aspx 我就不多做介绍了,就是图表渲染的基本代码,重点说下Default.aspx?action=export所对应的后端处理方法
asp.net服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 private string HandleImages(string url)
{

#region 启动进程保存图片
string r="";
try
{
Process p = new Process();
p.StartInfo.FileName = Server.MapPath(@"\GenerateImage\phantomjs.exe");
string outfile = Server.MapPath(@"\temp\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + ".png");
string jspath = Server.MapPath(@"\Scripts\rasterize.js ");
p.StartInfo.Arguments = string.Format(jspath + " " + url + " " + outfile);
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
//重定向标准输出
p.StartInfo.RedirectStandardOutput = true;
//重定向错误输出
p.StartInfo.RedirectStandardError = false; ;
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
if (!p.Start())
{ throw new Exception("无法启动Headless测试引擎."); }
string[] result = p.StandardOutput.ReadToEnd().Split(new char[] { '\r', '\n' });
r = outfile;
p.WaitForExit();
p.Close();
}
catch (Exception ex)
{
r = ex.ToString();
}
return r;
#endregion
}
java服务端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
PrintWriter out=response.getWriter();
Runtime rt = Runtime.getRuntime();
String path=getServletContext().getRealPath("/js/");
String pathExe=path+"\\phantomjs.exe ";
String pathJs=path+"\\rasterize.js";
String outPath="G:\\image\\img.jpg"; //这里可以写成动态路径
String url="http://localhost:8080/ImageTable/line.jsp";//这里路径可以从前端接收
String commonPath=pathExe+" "+pathJs+" "+url+" "+outPath;
Process p = rt.exec(commonPath);
InputStream is =p.getInputStream();
if (is!=null) {
out.print(outPath);
}
//通过标识 来证明
else{
out.print("获取图片路径有错误!");
}
}
  • 分析:这个方法传入一个url参数,即前端传过来需要渲染页面的URL。然后调用exe程序去生成这个页面的快照,exe 传入三个参数 rasterize.js路径即传入的URL图片的输出路径。最后生成快照返回生成的路径,由于我是ajax调用就没有通过流输出下载了。

(注意:这里有个BUG,phantomjs没法渲染动画效果的图表,因此这里需要把animate相关的属性关闭屌,才能渲染highchart)

在图表初始化的顶部加入

1
Highcharts.SVGRenderer.prototype.Element.prototype.animate = Highcharts.SVGRenderer.prototype.Element.prototype.attr;


最后效果图

DEMO下载地址:点击此处下载
若有问题请留言反馈!