1、前端部署node.js服务代码如下:
const express = require('express');
const { createCanvas } = require('canvas');
const echarts = require('echarts');
const bodyParser = require('body-parser');const app = express();
const port = 3000;app.use(bodyParser.json({ limit: '10mb' }));app.post('/render', (req, res) => {try {const { width = 800, height = 600, option } = req.body;// 创建一个空的 codes 对象const codes = {};// 使用 Function 构造器执行传入的 JS 配置代码const func = new Function('codes', option);func(codes);// 获取配置对象const config = codes.value;if (!config) {throw new Error('配置对象 codes.value 未定义');}// 创建画布并渲染const canvas = createCanvas(width, height);const chart = echarts.init(canvas);chart.setOption(config);// 返回 PNG 图像res.set('Content-Type', 'image/png');res.send(canvas.toBuffer());} catch (error) {console.error('渲染错误:', error.message);res.status(500).send(error.message);}
});app.listen(port, () => {console.log(`图表渲染服务运行在 http://localhost:${port}`);
});
2、后端访问请求数据,直接下载生成图片
import cn.hutool.core.io.FileUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;import java.io.File;
import java.util.HashMap;
import java.util.Map;public class EChartsRenderer {private static final String RENDER_SERVICE_URL = "http://localhost:3000/render";/*** 渲染ECharts图表为PNG字节数组(使用Hutool优化)*/public static byte[] renderChart(String config,int width,int height,boolean transparent) {// 使用Hutool构建JSON请求体Map<String, Object> paramMap = new HashMap<>();paramMap.put("width", width);paramMap.put("height", height);paramMap.put("transparent", transparent);paramMap.put("option", config); // 自动转换JSON// 发送HTTP POST请求HttpResponse response = HttpRequest.post(RENDER_SERVICE_URL).header("Content-Type", "application/json").body(JSONUtil.toJsonStr(paramMap)) // 自动序列化为JSON字符串.timeout(30 * 1000) // 30秒超时.execute();// 处理响应if (response.isOk()) {return response.bodyBytes();} else {String errorMsg = "图表渲染失败: HTTP " + response.getStatus() + " - " + response.body();throw new RuntimeException(errorMsg);}}/*** 渲染ECharts图表为PNG字节数组(默认大小)*/public static byte[] renderChart(String config) {return renderChart(config, 800, 600, false);}public static void main(String[] args) {// 准备ECharts配置(与之前相同)String echartsConfig = "codes.value = {\n" +" xAxis: {\n" +" type: 'category',\n" +" data: ['2021', '2022', '2023', '2024', '2025']\n" +" },\n" +" yAxis: {\n" +" type: 'value',\n" +" max: 40,\n" +" axisLabel: {\n" +" formatter: '{value}亿美元'\n" +" }\n" +" },\n" +" series: [\n" +" {\n" +" data: [5, 12, 24, 34, 50],\n" +" type: 'line',\n" +" itemStyle: {\n" +" color: '#4CAF50'\n" +" },\n" +" label: {\n" +" show: true,\n" +" position: 'top', // 标签显示在曲线顶部\n" +" formatter: '{c}亿美元' // 显示数值和单位\n" +" }\n" +" }\n" +" ]\n" +"};";// 渲染图表byte[] chartImage = EChartsRenderer.renderChart(echartsConfig);// 保存图片(示例)FileUtil.writeBytes(chartImage, new File("D:\\app\\echarts-chart.png"));System.out.println("图表已保存到D:\\app\\echarts-chart.png");}
}