Java后台生成ECharts图片【Java+Echarts+Phantomjs】
Java使用Echarts生成图片文章目录前言一、场景需求二、使用工具三、实现思路二、代码1.项目结构2.测试代码 EchartsTest.java2.JS脚本 echarts-convert.js3.测试数据代码 option.js总结前言Java后台使用Echarts生成图片。一、场景需求旧场景:前后端分离的项目,后台为Java,前端为VUE。VUE前端获取数据渲染生成echarts图表后,再
·
Java使用Echarts生成图片
文章目录
前言
- Java后台使用Echarts生成图片。
一、场景需求
- 旧场景:前后端分离的项目,后台为Java,前端为VUE。VUE前端获取数据渲染生成echarts图表后,再通过点击事件获取echart对象的base64编码发送给后台,后台根据base64通过Freemarker模板生成包含图片的Word。
- 新场景:前端不用等待获取数据渲染echarts图表,直接请求后台,获取echarts图表的base64编码,再通过Freemarker模板生成包含图片的Word。
二、使用工具
- Echarts:https://github.com/apache/echarts (下载ZIP,需要使用文件echarts/dist/echarts.min.js)
- Phantomjs:https://phantomjs.org/download.html
- JQuery:https://code.jquery.com/jquery-3.6.0.min.js (Ctrl+S保存到本地)
三、实现思路
- 前端发送请求,后台根据请求获取渲染echarts所需的数据option,通过phantomjs进行无界面浏览器的echarts渲染,渲染成功后获取echarts对象的base64编码。
四、代码
1.项目结构
echarts.min.js,echarts-convert.js,jquery-3.6.0.min.js 这个三个文件需要放在同一个文件夹中。
示例如下图:
2.测试代码 EchartsTest.java
package top.youngtse.demo.test.echarts;
import org.junit.Test;
import java.io.*;
/**
* @Title: EchartsTest
* @Date 2022/5/11 17:28
* @Author Youngtes
* @Description: 测试Echarts后台渲染生成图片
*/
public class EchartsTest {
/**
* phantomjs 路径
*/
private static String PHANTOMJS_PATH = "D:\\Tools\\phantomjs-2.1.1-windows\\bin\\phantomjs.exe";
/**
* echartsJs 路径
*/
private static String ECHARTS_PATH = "D:\\Space\\idea_space\\demo\\src\\main\\resources\\static\\echartjs\\echarts-convert.js";
/**
* echarts渲染所需数据 路径
*/
private static String OPTION_PATH = "D:\\Space\\idea_space\\demo\\src\\main\\resources\\temp\\option.js";
/**
* echarts获取图片base64编码URL头
*/
private static final String BASE64FORMAT = "data:image/png;base64,";
@Test
public void echartsTest() {
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_PATH + " " + ECHARTS_PATH + " -infile " + OPTION_PATH;
// + " -width " + 800 + " -height " + 600;
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);
}
}
3.JS脚本 echarts-convert.js
代码如下(示例):
(function () {
var system = require('system');
var fs = require('fs');
var config = {
// define the location of js files
JQUERY: 'jquery-3.6.0.min.js',
ECHARTS: 'echarts.min.js',
// default container width and height
DEFAULT_WIDTH: '600',
DEFAULT_HEIGHT: '700'
}, parseParams, render, pick, usage;
// 提示:命令格式
usage = function () {
console.log("\n" + "Usage: phantomjs echarts-convert.js -infile URL -width width -height height" + "\n");
};
// 选择是否存在设置长宽,否使用默认长宽
pick = function () {
var args = arguments, i, arg, length = args.length;
for (i = 0; i < length; i += 1) {
arg = args[i];
if (arg !== undefined && arg !== null && arg !== 'null' && arg != '0') {
return arg;
}
}
};
// 处理参数
parseParams = function () {
var map = {}, i, key;
if (system.args.length < 2) {
usage();
phantom.exit();
}
for (i = 0; i < system.args.length; i += 1) {
if (system.args[i].charAt(0) === '-') {
key = system.args[i].substr(1, i.length);
if (key === 'infile') {
// get string from file
// force translate the key from infile to options.
key = 'options';
try {
map[key] = fs.read(system.args[i + 1]).replace(/^\s+/, '');
} catch (e) {
console.log('Error: cannot find file, ' + system.args[i + 1]);
phantom.exit();
}
} else {
map[key] = system.args[i + 1].replace(/^\s+/, '');
}
}
}
return map;
};
render = function (params) {
var page = require('webpage').create(), createChart;
page.onConsoleMessage = function (msg) {
console.log(msg);
};
page.onAlert = function (msg) {
console.log(msg);
};
createChart = function (inputOption, width, height) {
var counter = 0;
function decrementImgCounter() {
counter -= 1;
if (counter < 1) {
console.log("The images load error");
}
}
function loadScript(varStr, codeStr) {
var script = $('<script>').attr('type', 'text/javascript');
script.html('var ' + varStr + ' = ' + codeStr);
document.getElementsByTagName("head")[0].appendChild(script[0]);
if (window[varStr] !== undefined) {
console.log('Echarts.' + varStr + ' has been parsed');
}
}
function loadImages() {
var images = $('image'), i, img;
if (images.length > 0) {
counter = images.length;
for (i = 0; i < images.length; i += 1) {
img = new Image();
img.onload = img.onerror = decrementImgCounter;
img.src = images[i].getAttribute('href');
}
} else {
console.log('The images have been loaded');
}
}
// load opitons
if (inputOption != 'undefined') {
// parse the options
loadScript('options', inputOption);
// disable the animation
options.animation = false;
}
// we render the image, so we need set background to white.
$(document.body).css('backgroundColor', 'white');
var container = $("<div>").appendTo(document.body);
container.attr('id', 'container');
container.css({
width: width,
height: height
});
// render the chart
var myChart = echarts.init(container[0]);
myChart.setOption(options);
// load images
loadImages();
return myChart.getDataURL();
};
// parse the params
page.open("about:blank", function (status) {
// inject the dependency js
page.injectJs(config.JQUERY);
page.injectJs(config.ECHARTS);
var width = pick(params.width, config.DEFAULT_WIDTH);
var height = pick(params.height, config.DEFAULT_HEIGHT);
// create the chart
var base64 = page.evaluate(createChart, params.options, width, height);
console.log(base64);
// define the clip-rectangle
console.log('\nbase64 complete');
// exit
phantom.exit();
});
};
// get the args
var params = parseParams();
// validate the params
if (params.options === undefined || params.options.length === 0) {
console.log("ERROR: No options or infile found.");
usage();
phantom.exit();
}
// render the image
render(params);
}());
4.测试数据代码 option.js
option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
}
5.结果展示
五、总结
- 实现步骤和解释都放在代码之中。
- 后续实现为:获取数据后,利用Freemarker模板生成内容不同的option.js文件,进行动态数据配置,渲染出不同的echarts。
- demo可能还存在问题和需要优化,个人能力有限,有问题希望大家提出一起讨论和交流。
- 参考原文:
https://blog.csdn.net/daroubaozi123/article/details/123072515
https://blog.csdn.net/letere/article/details/121862261
https://www.jb51.net/article/187540.htm
更多推荐
已为社区贡献1条内容
所有评论(0)