博客详情页背景图

服务端导出EChart

应用场景:报表中嵌入EChart图表,在后端导出报表希望将图表转为图片嵌入到导出的excel中

2026-01-06 · 后端

方案一

EChart官网介绍

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环境比较麻烦

方案二

gitee开源转换组件

思路:使用幽灵浏览器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环境的方式实现