服务端导出EChart
应用场景:报表中嵌入EChart图表,在后端导出报表希望将图表转为图片嵌入到导出的excel中
方案一
EChart官网有两个方式,都是基于node服务生成对应的svg或者png
1.后端引入echart.min.js资源文件
2.将node安装包放到服务器挂载盘中解压
3.执行导出的过程中将图表所需的js放到临时文件目录,生成demo.js
4.通过cmd命令行工具node所在位置执行demo.js文件
5.读取命令行返回的svg信息,组装后返回转为png
const echarts = require('echarts');
//此处可以替换为相对路径下大js文件
//const echarts = require('./echarts.min.js')
// 在 SSR 模式下第一个参数不需要再传入 DOM 对象
const chart = echarts.init(null, null, {
renderer: 'svg', // 必须使用 SVG 模式
ssr: true, // 开启 SSR
width: 400, // 需要指明高和宽
height: 300
});
// 像正常使用一样 setOption
chart.setOption({
//...
});
// 输出字符串
const svgStr = chart.renderToSVGString();
console.log(svgStr);
注:在读取svg返回数据时,不能通过readline()是否为null,判断是否还有数据,在node执行后不会中断线程,可以以</svg>字符串判断,中断对应线程执行
第二种方法参考官方链接介绍 这种方法需要安装node环境比较麻烦
方案二
思路:使用幽灵浏览器PhantomJS,基于服务端浏览器启动一个web浏览器,通过后端访问端口,传递相关的数据处理,通过浏览器加载js和渲染界面后,通过截图返回image
启动web服务
/**
* 服务
* @param params
*/
Convert.prototype.server = function (params) {
var server = require('webserver').create(), // 服务端
convert = this;
var listen = server.listen(params.port, function (request, response) {
/**
* 输出
* @param data
* @param success
*/
function write(data, success, msg) {
response.statusCode = 200;
response.headers = {
'Cache': 'no-cache',
'Content-Type': 'application/json;charset=utf-8'
};
response.write(convert.serverResult(data, success, msg));
response.close();
}
//获取参数
var args = convert.serverGetArgs(request);
if (args.opt !== undefined) {
var check = convert.serverCheckAndSet(params, args);
if (check) {
convert.client(params, write);
} else {
write("", false, "failed to get image, please check parameter [opt] is a JSON");
}
} else {
write("", false, "failed to get image, missing parameter [opt]");
}
});
// 判断服务是否启动成功
if (!listen) {
this.error("could not create echarts-convert server listening on port " + params.port);
} else {
console.log("echarts-convert server start success. [pid]=" + system.pid);
}
};
通过Java传递对参数,前端读取解析
function createEchartsDom(params) {
// 动态加载js,获取options数据
$('<script>')
.attr('type', 'text/javascript')
.html('var options = ' + params.opt)
.appendTo(document.head);
// 取消动画,否则生成图片过快,会出现无数据
if (options !== undefined) {
options.animation = false;
}
// body背景设置为白色
$(document.body).css('backgroundColor', 'white');
// echarts容器
var container = $("<div>")
.attr('id', 'container')
.css({
width: params.width,
height: params.height
}).appendTo(document.body);
var eChart = echarts.init(container[0]);
eChart.setOption(options);
}
总结:
1.如果不允许引入第三方组件,推荐在挂载盘制定路径放置一个nodeJs解压文件,通过后端组合js都方式,使用nodeJs执行js生成svg解决
2.如果运行第三方组件更加推荐安装nodeJs环境的方式实现