赞
踩
生成图的前提下载 phantomjs-2.1.1-windows 与对应的js
一种方式和网上大多方式大同小异 直接上码:
@Component public class EchartsUtil { /** * 临时文件夹路径 */ @Value("${file.path}") private String TEMP_FILE_PATH; @Value("${echartHost}") private String echartHost; private static final String SUCCESS_CODE = "1"; private static final Logger logger = LoggerFactory.getLogger(EchartsUtil.class); private static EchartsUtil EchartsUtil; @PostConstruct public void init() { EchartsUtil=this; EchartsUtil.TEMP_FILE_PATH=this.TEMP_FILE_PATH; EchartsUtil.echartHost=this.echartHost; } public static String generateEchartsBase64(String option) throws ClientProtocolException, IOException { String base64 = ""; if (option == null) { return base64; } option = option.replaceAll("\\s+", "").replaceAll("\"", "'"); // 将option字符串作为参数发送给echartsConvert服务器 Map<String, String> params = new HashMap<>(); params.put("opt", option); String response = HttpUtil.post(EchartsUtil.echartHost, params, "utf-8"); // 解析echartsConvert响应 JSONObject responseJson = JSON.parseObject(response); String code = responseJson.getString("code"); // 如果echartsConvert正常返回 if (SUCCESS_CODE.equals(code)) { base64 = responseJson.getString("data"); } // 未正常返回 else { String string = responseJson.getString("msg"); throw new RuntimeException(string); } return base64; } public static String getImage(Map<String, Object> datas) throws IOException { String option = null; try { if (!datas.containsKey("ftl")){ logger.error("没有指定生成图表的模板!"); return null; } option = FreemarkerUtil.generateString((String) datas.get("ftl"), String.valueOf(datas.get("folder")), datas); } catch (TemplateException e) { logger.error(e.getMessage()); } // 根据option参数 String base64 = generateEchartsBase64(option); File file = new File(EchartsUtil.TEMP_FILE_PATH); if(!file.exists()) { // 如果不存在就创建文件 file.mkdir(); } BASE64Decoder decoder = new BASE64Decoder(); String name= String.valueOf(UUID.randomUUID()); try (OutputStream out = new FileOutputStream(EchartsUtil.TEMP_FILE_PATH+name+".jpg")){ // 解密 byte[] b = decoder.decodeBuffer(base64); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) { b[i] += 256; } } out.write(b); out.flush(); return EchartsUtil.TEMP_FILE_PATH+name+".jpg"; } }
public class FreemarkerUtil { private static final String path = FreemarkerUtil.class.getClassLoader().getResource("").getPath(); public static String generateString(String templateFileName, String templateDirectory, Map<String, Object> datas) throws IOException, TemplateException { Configuration configuration = new Configuration(Configuration.VERSION_2_3_0); // 设置默认编码 configuration.setDefaultEncoding("UTF-8"); configuration.setClassicCompatible(true); //获取模板地址 configuration.setClassForTemplateLoading(FreemarkerUtil.class,templateDirectory); // 生成模板对象 Template template = configuration.getTemplate(templateFileName); // 将datas写入模板并返回 try (StringWriter stringWriter = new StringWriter()) { template.process(datas, stringWriter); stringWriter.flush(); return stringWriter.getBuffer().toString(); } } }
public class HttpUtil { public static String post(String url, Map<String, String> params, String charset) throws ClientProtocolException, IOException { String responseEntity = ""; // 创建CloseableHttpClient对象 CloseableHttpClient client = HttpClients.createDefault(); // 创建post方式请求对象 HttpPost httpPost = new HttpPost(url); // 生成请求参数 List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(); if (params != null) { for (Map.Entry<String, String> entry : params.entrySet()) { nameValuePairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } } // 将参数添加到post请求中 httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, charset)); // 发送请求,获取结果(同步阻塞) CloseableHttpResponse response = client.execute(httpPost); // 获取响应实体 HttpEntity entity = response.getEntity(); if (entity != null) { // 按指定编码转换结果实体为String类型 responseEntity = EntityUtils.toString(entity, charset); } // 释放资源 EntityUtils.consume(entity); response.close(); return responseEntity; }
创建模板:
{ title: { text: ${title} }, xAxis: { type: 'category', data: ${aoxList} }, yAxis: { type: 'value' }, color:[ ${colordata} ], series: [ { data: ${aoList}, type: 'bar' } ] }
测试: @GetMapping("12323") public String test3(){ //制造数据 List<String> aoxList = new ArrayList<>(); aoxList.add("2"); aoxList.add("4"); aoxList.add("7");aoxList.add("9"); aoxList.add("10"); aoxList.add("9"); aoxList.add("8"); aoxList.add("8"); aoxList.add("7"); List<String> aoList = new ArrayList<>(); aoList.add("1"); aoList.add("4"); aoList.add("7");aoList.add("9"); aoList.add("10"); aoList.add("10"); aoList.add("10"); aoList.add("10"); aoList.add("10"); // 模板参数 HashMap<String, Object> datas = new HashMap<>(); //aohour、aoList、aoxList对应模板/template/option.ftl中的x和y轴的名字,模板可自行修改, //ftl 为设置模板的名字。路径在/templates下 datas.put("title",JSON.toJSONString("wxw图示")); datas.put("colordata", JSON.toJSONString("#000000")); datas.put("aoxList", JSON.toJSONString(aoxList)); datas.put("aoList", JSON.toJSONString(aoList)); datas.put("ftl", "option.ftl"); datas.put("folder","/Columnar"); try { System.out.println( EchartsUtil.getImage(datas)); } catch (IOException e) { e.printStackTrace(); } return "ok"; }
此方法前提:
没配置环境变量的话:
显示echarts-convert server start success. [pid]=10364
表明启动成功
此方式作者发现的问题:例如饼图还有一些复杂的图示是无法生成,不报错,请求一直阻塞在链接6666服务上面;
最后发现了第二种方式,
public class EchartGenerate { public static String generateEChart(String options) { String dataPath = writeFile(options); String fileName= UUID.randomUUID()+ ".jpg"; String path = ConstantConfigUtil.FILE_PATH +fileName; try { File file = new File(path); if (!file.exists()) { File dir = new File(file.getParent()); dir.mkdirs(); file.createNewFile(); } String cmd = ConstantConfigUtil.PHANTOM_JS_PATH +" "+ ConstantConfigUtil.ECHARTS_JS_PATH + " -infile " + dataPath + " -outfile " + path; System.out.println(cmd); Process process = Runtime.getRuntime().exec(cmd); BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = ""; while ((line = input.readLine()) != null) { System.out.println(line); } input.close(); } catch (IOException e) { e.printStackTrace(); }finally{ return path; } } public static String writeFile(String options) { String dataPath=ConstantConfigUtil.FILE_PATH+ UUID.randomUUID() +".json"; try { File writename = new File(dataPath); if (!writename.exists()) { File dir = new File(writename.getParent()); dir.mkdirs(); writename.createNewFile(); } BufferedWriter out = new BufferedWriter(new FileWriter(writename)); out.write(options); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } return dataPath; } }
public static String getImage2(Map<String, Object> datas) throws IOException { String option = null; try { if (!datas.containsKey("ftl")){ logger.error("没有指定生成图表的模板!"); return null; } option = FreemarkerUtil.generateString((String) datas.get("ftl"), String.valueOf(datas.get("folder")), datas); } catch (TemplateException e) { logger.error(e.getMessage()); } // 根据option参数 String path = EchartGenerate.generateEChart(option); return path; }
测试:
@GetMapping("1232") public String test2(){ //制造数据 List<Map<String,Object>> data = new ArrayList<>(); for(int i=1;i<6;i++){ HashMap<String,Object> value=new HashMap<String,Object>(); value.put("value",i+1); value.put("name",String.valueOf(i+1)); data.add(value); } System.out.println( JSON.toJSONString(data)); // 模板参数 HashMap<String, Object> datas = new HashMap<>(); //aohour、aoList、aoxList对应模板/template/option.ftl中的x和y轴的名字,模板可自行修改, //ftl 为设置模板的名字。路径在/templates下 // datas.put("title",JSON.toJSONString("123图示")); // datas.put("cakeData",JSON.toJSONString(data)); datas.put("ftl", "option.ftl"); datas.put("folder","/area"); try { System.out.println(EchartsUtil.getImage2(datas)); } catch (IOException e) { e.printStackTrace(); } return "ok"; }
问题:刚开始按照网上的方式 配置了环境变量:
故:
这里的值为
但是请求一直报错,生成的图片也无法打开:
但是这个命令直接用cmd执行时成功的
最后只能使用对应的绝对路径: 生成成功;
以上是结合个人见解与网上信息所得。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。