# PhantomJSForEcharts **Repository Path**: liuzidong/PhantomJSForEcharts ## Basic Information - **Project Name**: PhantomJSForEcharts - **Description**: PhantomJS+Echarts生成图片 - **Primary Language**: Unknown - **License**: AFL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 0 - **Created**: 2019-09-02 - **Last Updated**: 2023-08-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## PhantomJS+Echarts生成图片 ### 参考资料 #### 1. [ECharts - Java类库](https://gitee.com/free/ECharts) #### 2. [SpringBoot系列 - 集成Echarts导出图片](https://www.xncoding.com/2017/08/19/spring/sb-echarts.html) #### 3. [base64 To File](https://base64.guru/converter/decode/file) #### 4. [Java实现网页截屏功能(图片下载功能)的几种方式(整理)](https://blog.csdn.net/wanglq0086/article/details/60761614) #### 5. [基于PhantomJS+Highcharts/echarts的服务器端图表渲染方案](https://github.com/billfeller/billfeller.github.io/issues/85) #### 6. [ECharts服务端渲染方案](https://echarts.baidu.com/tutorial.html#%E6%9C%8D%E5%8A%A1%E7%AB%AF%E6%B8%B2%E6%9F%93) #### 7. [使用Java调用PhantomJS动态导出ECharts图片到Word文件中](https://blinkfox.github.io/2018/10/01/hou-duan/java/shi-yong-java-diao-yong-phantomjs-dong-tai-dao-chu-echarts-tu-pian-dao-word-wen-jian-zhong/) #### 8. [java使用phantomjs进行截图](https://juejin.im/post/5bbb13775188255c9f06cf77) #### 9. [PhantomJS文档](https://javascript.ruanyifeng.com/tool/phantomjs.html#toc4) [腾讯](https://imweb.io/topic/560b402ac2317a8c3e08621c) #### 10. [Phantomjs教你如何实现浏览器截图并上传截图文件 #15](https://github.com/PaicFE/blog/issues/15) #### 11. [PhantomJS在服务端生成ECharts图片](https://gitee.com/saintlee/echartsconvert) #### 12. [java后端生成echarts图片](https://www.jianshu.com/p/dfc28fd7d786) #### 13. [Java 用 PhantomJS+ECharts 后台生成图片](https://blog.csdn.net/leftwukaixing/article/details/89449071) #### 14. [Echarts + WebSocket实现图片生成](https://github.com/yidao620c/SpringBootBucket/tree/master/springboot-echarts) ### phantomjs #### [phantomjs的镜像网站](http://npm.taobao.org/dist/phantomjs) ``` PhantomJS是一个基于webkit内核的无头浏览器,即没有UI界面的一个浏览器,只是其内的点击、翻页等人为相关操作需要程序设计实现。 PhantomJS提供JavaScript API接口,即通过编写js程序可以直接与webkit内核交互,在此之上可以结合Java语言等,通过java调用js等相关操作,从而解决了以前c/c++才能比较好的基于webkit开发优质采集器的限制。 可通过:npm install phantomjs -g 安装 检查版本:phantomjs --version ``` ### 方案1: 半自动方案:ECharts+Java实现,ECharts>Base64>ToImages ``` 直接访问:http://localhost/echarts/line.html 获取ECharts的base64自动请求url,Java后台生成图片。 优点:实现方便 不足:手工打开 ``` ### 方案2: 全动方案:纯Java实现,Phantomjs的API ``` 提供url(http://localhost/echarts/createPhantomjs),Java后台调用Phantomjs的API生成图片 优点:实现方便 ``` ### 方案3: [使用PhantomJS在服务端生成ECharts图片](https://gitee.com/saintlee/echartsconvert) ``` 手工启动PhantomJS服务器,通过构造ECharts的Options数据调用Java生成图片。 ``` ##### 优化点:将相关JS放置资源文件下,全部通过Java后台实现调用。 ### 关键点 #### 1. 环境变量配置 ``` 将phantomjs添加至环境变量中。 windows: 右键我的电脑->属性->高级系统设置->高级->环境变量->用户变量/系统变量->Path=D:\phantomjs\bin; 或 cmd->set path=%path%;D:\phantomjs\bin linux: vi /etc/profile export PATH=$PATH:/usr/phantomjs/bin ``` #### 2. application.properties配置 ``` phantomjs.exec.path=D:/phantomjs-2.1.1-windows/bin/phantomjs # 通过调用myChart.getDataURL()得到base64,调用java直接生成图片,适用于不复杂的场景 phantomjs.echarts.get.base64.call.java.url=http://localhost/echarts/line.html phantomjs.call.java.url=http://localhost/echarts/phantomjs image.root.path=D:/images image.width=850 image.height=850 ``` #### 3. Java配置 ``` 1、拼接cmd命令并执行>启动服务 private static String getCmd() throws FileNotFoundException { StringBuilder cmd = new StringBuilder(); cmd.append("D:/phantomjs-2.1.1-windows/bin/phantomjs").append(SP); cmd.append(getEchartsRootPath() + "/echarts-convert.js").append(SP); cmd.append("-s").append(SP); return cmd.toString(); } private static String getEchartsRootPath() throws FileNotFoundException { return ResourceUtils.getFile("classpath:phantomjs/echarts").getAbsolutePath(); } public static void startPhantomjs() throws FileNotFoundException { Runtime rt = Runtime.getRuntime(); String cmdStr = getCmd(); log.info("执行命令:{}", cmdStr); try { rt.exec(cmdStr); } catch (IOException e) { log.error("执行phantomjs的指令失败!请检查是否安装有PhantomJs的环境或配置path路径!PhantomJs详情参考这里:http://phantomjs.org", e); } log.info("打开地址完成!"); } 2、拼接ECharts的Options,调用HttpClients的API生成。 private static void createImage() throws Exception { // String url = "http://localhost:9090"; // 不必要的空格最好删除,字符串请求过程中会将空格转码成+号 String optJson = "{title:{text:'ECharts 示例'},tooltip:{},legend:{data:['销量']}," + "xAxis:{data:['衬衫','羊毛衫','雪纺衫','裤子','高跟鞋','袜子']},yAxis:{}," + "series:[{name:'销量',type:'bar',data:[5,20,36,10,10,20]}]}"; Map map = new HashMap<>(); map.put("opt", optJson); map.put("echartsRoot", getEchartsRootPath()); try { String post = post(url, map, "utf-8"); System.out.println(post); Map jsonMap = new Gson().fromJson(post, Map.class); String base64Info = (String) jsonMap.get("data"); Base64ImgsUtil.base64StringToImage(base64Info, "D:\\images\\" + UUID.randomUUID().toString() + ".png"); } catch (ParseException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // post请求 public static String post(String url, Map map, String encoding) throws ParseException, IOException { String body = ""; // 创建httpclient对象 CloseableHttpClient client = HttpClients.createDefault(); // 创建post方式请求对象 HttpPost httpPost = new HttpPost(url); // 装填参数 List nvps = new ArrayList<>(); if (map != null) { for (Entry entry : map.entrySet()) { nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } } // 设置参数到请求对象中 httpPost.setEntity(new UrlEncodedFormEntity(nvps, encoding)); // 执行请求操作,并拿到结果(同步阻塞) CloseableHttpResponse response = client.execute(httpPost); // 获取结果实体 HttpEntity entity = response.getEntity(); if (entity != null) { // 按指定编码转换结果实体为String类型 body = EntityUtils.toString(entity, encoding); } EntityUtils.consume(entity); // 释放链接 response.close(); return body; } ```