java生成echarts图片自动保存到本地(无页面浏览器渲染)
最近碰到一个导出word的功能,需要用到一些在前端展示的echarts图片,但是又不能手动去下载保存,经过查资料找到使用phantomjs可以将输入的js文件转成base64编码返回。
·
最近碰到一个导出word的功能,需要用到一些在前端展示的echarts图片,但是又不能手动去下载保存,经过查资料找到使用phantomjs可以将输入的js文件转成base64编码返回。
1、下载phantomjs
https://pan.baidu.com/s/14M-P83XCUcwl9dJBwctuJg?pwd=tznp
2、配置环境
1.1 环境配置
下载后解压文件到没有中文的目录下,点击 我的电脑-属性-高级系统设置-环境变量-系统变量-Path-编辑-新建-输入地址-保存
1.2 测试是否成功添加
找一个目录,cmd进入命令行,输入
phantomjs -v
出现版本号,说明配置正确
3、测试是否可用
3.1 测试phantomjs 命令是否可用
进入解压的文件夹,文件夹下有个examples文件夹,其中有很多js文件,cmd进入命令行后输入以下命令测试phantomjs 是否可用
phantomjs hello.js
出现Hello,world!说明配置正确
4、编写代码
4.1 新建springboot项目
idea内新建springboot项目,这个不会的私信我[dog头][dog头]
4.2 添加依赖
后续需要将对象转成js文件,需要用到gson依赖,如果只是想测试,不需要添加任何依赖。
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version>
</dependency>
4.3 编写测试代码
4.3.1 构造echartsOption.js文件,就是echarts的运行脚本
也可以自己去echarts官网上找个例子新建一个js文件就行
echartsOption.js文件可以直接放到echarts编辑器中运行看结果
option = {
"title": {
"text": "差异性分析",
"subtext": "",
"x": "left"
},
"legend": {
"orient": "vertical",
"left": "left",
"bottom": "bottom",
"show": true,
"data": []
},
"tooltip": {
"trigger": "item",
"axisPointer": {
"type": "shadow"
},
"textStyle": {
"fontSize": 12
}
},
"toolbox": {
"show": true,
"feature": {
"saveAsImage": {
"show": true
}
}
},
"grid": {
"left": "3%",
"right": "4%",
"bottom": "35px",
"containLabel": true
},
"xAxis": {
"type": "category",
"axisLabel": {
"interval": 0,
"rotate": 45,
"textStyle": {
"fontStyle": "normal",
"fontWeight": "normal"
}
},
"data": [
"A",
"B",
"C",
"D"
],
"boundaryGap": true,
"nameGap": 30,
"splitArea": {
"show": false
},
"splitLine": {
"show": false
}
},
"yAxis": {
"axisLabel": {},
"type": "value",
"splitArea": {
"show": true
}
},
"series": [
{
"name": "质量区间",
"type": "boxplot",
"data": [
[
106.34,
107.8125,
109.21,
110.4,
112.33
],
[
106.98,
108.1775,
109.365,
110.1875,
111.9
],
[
105.72,
107.515,
108.545,
110.5125,
113.65
],
[
104.57,
106.6575,
107.825,
109.2575,
113.1574
]
],
"tooltip": {}
},
{
"name": "综合评价",
"type": "line",
"smooth": "true",
"data": [],
"z": 10
}
]
}
4.3.2 编写java测试代码
import sun.misc.BASE64Decoder;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class TestEcharts {
/**
* echartsJs 路径
*/
private static String ECHARTS_PATH = "F:\\work\\s\\echarts-convert\\echarts-convert.js";
private static String OPTION_PATH = "F:\\work\\s\\echarts-convert\\echartsOption.js";
private static String OUT_PATH = "E:\\time\\222\\java\\demo4\\src\\main\\resources\\";
/**
* echarts获取图片base64编码URL头
*/
private static final String BASE64FORMAT = "data:image/png;base64,";
public static void main(String[] args)throws Exception {
BufferedReader input = null;
String line;
String base64 = "";
try {
/**
* 命令格式:
* phantomjs echarts-convert.js -infile optionURl -width width -height height
* 可选参数:-width width -height height
* 备注:
* phantomjs添加到环境变量中后可以直接使用,这里防止环境变量配置问题所以直接使用绝对路径
*/
String cmd = " phantomjs " + ECHARTS_PATH + " -infile " + OPTION_PATH
+ " -width " + 800 + " -height " + 800;
Process process = Runtime.getRuntime().exec(cmd);
System.out.println(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();
}
//删除js文件
// Files.delete(Paths.get(OPTION_PATH));
}
System.out.println(base64);
getFileFromBase64(base64);
}
public static File getFileFromBase64(String base) throws Exception {
String base64Pic = base;
File file = null;
Map<String, Object> resultMap = new HashMap<String, Object>();
if (base64Pic == null||base=="") { // 图像数据为空
resultMap.put("resultCode", 0);
resultMap.put("msg", "图片为空");
} else {
BASE64Decoder decoder = new BASE64Decoder();
String baseValue = base64Pic.replaceAll(" ", "+");//前台在用Ajax传base64值的时候会把base64中的+换成空格,所以需要替换回来。
byte[] b = decoder.decodeBuffer(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 = OUT_PATH + nowDate ;
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;
}
}
运行结果:
4.3.3 构造js文件
如何构造phantomjs 运行需要的js文件呢?
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class EChartsToJs {
public static void main(String[] args) {
// 创建 ECharts 的 option 对象
ChartOption option = new ChartOption();
// 模拟添加数据
option.setTitle(new Title("规格差异性分析"));
option.setTooltip(new Tooltip("item"));
option.setxAxis(new XAxis(new String[]{"A",
"B",
"C",
"D"}));
option.setyAxis(new YAxis("value"));
Series series = new Series();
series.setName("箱线图");
series.setType("boxplot");
series.setData(new double[][]{
{107.35, 108.02, 106.42, 108.14, 107.19},
{108.2, 109.55, 109.7, 109.95, 108.95},
{109.45, 106.33, 109.43, 107.99, 110.93},
{110.05, 109.65, 108.9, 109.78, 109.08}
});
option.setSeries(new Series[]{series});
//将 option 对象转换为 JSON
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOption = gson.toJson(option);
//将 JSON 写入到 JavaScript 文件中
String jsFilePath = "E:\\3\\echarts\\echartsOption.js";
try (BufferedWriter writer = new BufferedWriter(new FileWriter(jsFilePath))) {
writer.write("option = " + jsonOption + ";");
System.out.println("ECharts option 已写入文件: " + jsFilePath);
} catch (IOException e) {
e.printStackTrace();
}
}
// 定义 ChartOption 类
static class ChartOption {
private Title title;
private Tooltip tooltip;
private XAxis xAxis;
private YAxis yAxis;
private Series[] series;
public Title getTitle() {
return title;
}
public void setTitle(Title title) {
this.title = title;
}
public Tooltip getTooltip() {
return tooltip;
}
public void setTooltip(Tooltip tooltip) {
this.tooltip = tooltip;
}
public XAxis getxAxis() {
return xAxis;
}
public void setxAxis(XAxis xAxis) {
this.xAxis = xAxis;
}
public YAxis getyAxis() {
return yAxis;
}
public void setyAxis(YAxis yAxis) {
this.yAxis = yAxis;
}
public Series[] getSeries() {
return series;
}
public void setSeries(Series[] series) {
this.series = series;
}
}
// 其余的类定义
static class Title {
private String text;
public Title(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
static class Tooltip {
private String trigger;
public Tooltip(String trigger) {
this.trigger = trigger;
}
public String getTrigger() {
return trigger;
}
public void setTrigger(String trigger) {
this.trigger = trigger;
}
}
static class XAxis {
private String[] data;
public XAxis(String[] data) {
this.data = data;
}
public String[] getData() {
return data;
}
public void setData(String[] data) {
this.data = data;
}
}
static class YAxis {
private String type;
public YAxis(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
static class Series {
private String name;
private String type;
// private int[][] data;
private double[][] data;
public void setName(String name) {
this.name = name;
}
public void setType(String type) {
this.type = type;
}
public void setData(double[][] data) {
this.data = data;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public double[][] getData() {
return data;
}
}
}
实际上以上代码都只是为了构造出phantomjs命令行运行所需的代码,实际还是命令行运行。
写在最后:
不设置什么vip可见,关注可见,因为我也是参考了一些其他的代码写出来的,就想为需要的人分享一下,希望对你有所帮助
更多推荐
已为社区贡献1条内容
所有评论(0)