java生成动态图片例如统计图雷达图。可以用到动态导出word,pdf文件中。
工具类
package com.wjdc.web.controller.echarts;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @Title: EchartsTest
* @Date 2022/5/11 17:28
* @Author Yinan
* @Description: 测试Echarts后台渲染生成图片
*/
public class EchartsUtil {
/**
* echarts获取图片base64编码URL头
*/
private static final String BASE64FORMAT = "data:image/png;base64,";
// windows
private static final String ECHARTS_PATH = "D:\\phantomjs\\echarts-convert.js";
// linux
// private static final String ECHARTS_PATH = "/root/ceshi/echarts-convert.js";
private static final String options = "{\n" +
"\t\"grid\": {\n" +
"\t\t\"left\": \"10%\",\n" +
"\t\t\"right\": \"4%\",\n" +
"\t\t\"bottom\": \"3%\",\n" +
"\t\t\"containLabel\": true\n" +
"\t},\n" +
"\t\"tooltip\": {\n" +
"\t\t\"trigger\": \"axis\"\n" +
"\t},\n" +
"\t\"splitLine\": {\n" +
"\t\t\"show\": true,\n" +
"\t\t\"lineStyle\": {\n" +
"\t\t\t\"type\": \"dashed\",\n" +
"\t\t\t\"color\": \"#aea7ac\"\n" +
"\t\t}\n" +
"\t},\n" +
"\t\"xAxis\": {\n" +
"\t\t\"boundaryGap\": false,\n" +
"\t\t\"type\": \"value\",\n" +
"\t\t\"min\": 45,\n" +
"\t\t\"max\": 95,\n" +
"\t\t\"data\": [\n" +
"\t\t\t\"Mon\",\n" +
"\t\t\t\"Tue\",\n" +
"\t\t\t\"Wed\",\n" +
"\t\t\t\"Thu\",\n" +
"\t\t\t\"Fri\",\n" +
"\t\t\t\"Sat\",\n" +
"\t\t\t\"Sun\"\n" +
"\t\t]\n" +
"\t},\n" +
"\t\"yAxis\": {\n" +
"\n" +
"\t\t\"boundaryGap\": false,\n" +
"\t\t\"splitLine\": {\n" +
"\t\t\t\"show\": true,\n" +
"\t\t\t\"lineStyle\": {\n" +
"\t\t\t\t\"type\": \"dashed\",\n" +
"\t\t\t\t\"color\": \"#aea7ac\"\n" +
"\t\t\t}\n" +
"\t\t},\n" +
"\t\t\"type\": \"category\",\n" +
"\t\t\"axisLabel\": {\n" +
"\t\t\t\"formatter\": \"{value}\",\n" +
// "\t\t\t\"fontWeight\": \"bold\",\n" +
"\t\t\t\"fontSize\": 20\n" +
"\t\t}\n" +
"\t},\n" +
"\t\"series\": [{\n" +
"\t\t\t\"name\": \"分数\",\n" +
"\t\t\t\"type\": \"line\",\n" +
"\t\t\t\"data\": [\n" +
"\t\t\t\t10,\n" +
"\t\t\t\t11,\n" +
"\t\t\t\t13,\n" +
"\t\t\t\t11,\n" +
"\t\t\t\t12,\n" +
"\t\t\t\t12,\n" +
"\t\t\t\t9\n" +
"\t\t\t],\n" +
"\t\t\t\"label\": {\n" +
"\t\t\t\t\"show\": true,\n" +
"\t\t\t\t\"position\": \"top\"\n" +
"\t\t\t},\n" +
"\t\t\t\"markPoint\": {}\n" +
"\t\t},\n" +
"\t\t{\n" +
"\t\t\t\"name\": \"常模线\",\n" +
"\t\t\t\"type\": \"line\",\n" +
"\t\t\t\"data\": [\n" +
"\t\t\t\t1, -2,\n" +
"\t\t\t\t2,\n" +
"\t\t\t\t5,\n" +
"\t\t\t\t3,\n" +
"\t\t\t\t2,\n" +
"\t\t\t\t0\n" +
"\t\t\t],\n" +
"\t\t\t\"label\": {\n" +
"\t\t\t\t\"show\": true,\n" +
"\t\t\t\t\"position\": \"top\"\n" +
"\t\t\t}\n" +
"\t\t}\n" +
"\t]\n" +
"}" ;
public static String echartsToBase64(List<String> nameList, List<Double> doubleScoreList, List<Double> doubleScoreListLevel) throws Exception {
BufferedReader input = null;
String line;
String base64 = "";
// 将options转换为JSONObject
JSONObject parseObject = JSONObject.parseObject(options);
// 将yAxis中的data替换为nameList
JSONObject parseObject1 = JSONObject.parseObject(parseObject.getString("yAxis"));
parseObject1.put("data", nameList);
parseObject.put("yAxis", parseObject1);
// 将series中的data替换为doubleScoreList
JSONArray jsonArray = JSONArray.parseArray(parseObject.getString("series"));
jsonArray.getJSONObject(0).put("data", doubleScoreList);
//判断是否有常模线
if (doubleScoreListLevel != null && doubleScoreListLevel.size() > 0) {
jsonArray.getJSONObject(1).put("data", doubleScoreListLevel);
}else {
jsonArray.remove(1);
}
parseObject.put("series", jsonArray);
// 将JSONObject转换为String 写入文件 并获取文件路径
String dataPath = writeFile(parseObject.toJSONString());
try {
/**
* 命令格式:
* phantomjs echarts-convert.js -infile optionURl -width width -height height
* 可选参数:-width width -height height
* 备注:
* phantomjs添加到环境变量中后可以直接使用,这里防止环境变量配置问题所以直接使用绝对路径
*/
String cmd = " phantomjs " + ECHARTS_PATH + " -infile " + dataPath
+ " -width " + 650 + " -height " + 800;
Process process = Runtime.getRuntime().exec(cmd);
/**
* 获取控制台输出信息
* 通过JS中使用console.log()打印输出base64编码
* 获取进程输入流,进行base64编码获取
*/
input = new BufferedReader(new InputStreamReader(process.getInputStream()));
while ((line = input.readLine()) != null) {
if (line.startsWith(BASE64FORMAT)) {
base64 = line;//.replace(BASE64FORMAT, "");
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
input.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// System.out.println(base64);
// getFileFromBase64(base64);
return base64;
}
/*
*
* options生成文件存储
*/
public static String writeFile(String options) {
// windows
String dataPath = "D:\\" + UUID.randomUUID().toString().substring(0, 8) + ".json";
// linux
// String dataPath = "/root/ceshi/" + UUID.randomUUID().toString().substring(0, 8) + ".json";
try {
// option写入文本文件 用于执行命令
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;
}
//base64转file保存到本地
public File getFileFromBase64(String base) throws Exception {
String base64Pic = base;
File file = null;
Map<String, Object> resultMap = new HashMap<String, Object>();
if (base64Pic == null) { // 图像数据为空
resultMap.put("resultCode", 0);
resultMap.put("msg", "图片为空");
} else {
Base64.Decoder decoder = Base64.getDecoder();
String baseValue = base64Pic.replaceAll(" ", "+");//前台在用Ajax传base64值的时候会把base64中的+换成空格,所以需要替换回来。
byte[] b = decoder.decode(baseValue.replace("data:image/png;base64,", ""));//去除base64中无用的部分
base64Pic = base64Pic.replace("base64,", "");
SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd");
String nowDate = df2.format(new Date());
String imgFilePath = "f:\\" + nowDate + "\\" + System.currentTimeMillis();
File file1 = new File(imgFilePath);
if (!file1.exists() && !file1.isDirectory()) {//判断文件路径下的文件夹是否存在,不存在则创建
file1.mkdirs();
}
try {
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {// 调整异常数据
b[i] += 256;
}
}
file = new File(imgFilePath + "\\" + System.currentTimeMillis()+".png");
// 如果要返回file文件这边return就可以了,存到临时文件中
OutputStream out = new FileOutputStream(file.getPath());
out.write(b);
out.flush();
out.close();
} catch (Exception e) {
resultMap.put("resultCode", 0);
resultMap.put("msg", "存储异常");
}
}
return file;
}
}
具体使用,获取对应的图片base64
EchartsUtil.echartsToBase64(pdfData.getNameList(), pdfData.getDoubleScoreList(), pdfData.getDoubleScoreListLevel()))