.NetCore后台生成Echarts图表(chromedriver+Selenium.WebDriver)

有些需求比如生成的报告,需要添加Echarts图表,作为后台任务,echarts也需要后台执行,所以需要用到无头浏览器,这个没什么可说的。下面说下实践步骤,可直接用到项目里。

环境:Windows 11, Selenium.WebDriver(4.5.1), chromedriver.exe(版本107.0.5304.62), google浏览器(版本 107.0.5304.107),.Net 6。

注意chromedriver.exe和google浏览器的版本问题,要相互兼容,官网有相关说明。

以共用接口为例,创建一个后台生成echarts图片的接口项目:

1. 添加Selenium.WebDriver(4.5.1) package,并将chromedriver.exe复制到项目里(根目录),属性设置 复制到输出目录 为 如果较新则复制,这样发布的时候会跟随应用程序一起发布。

2. 创建一个视图模型控制器,添加代码

        /// <summary>
        /// 渲染echart图形
        /// </summary>
        /// <returns>IActionResult</returns>
        public IActionResult GenImg()
        {
            return View();
        }

3. 添加视图,添加如下代码, 注意引用echarts.js

@{
    Layout = null;
}
<body style="margin:0px;">
    <div id="chartContainer" style="width: 1102px; height: 640px; padding: 0px; margin: 0px;"></div>
</body>
<script src="~/echarts.min.js"></script>
<script>
</script>

4. 创建API控制器,添加如下代码:

        /// <summary>
        /// 导出图表图片,返回一个 base64 的 URL,可以设置为Image的src。
        /// </summary>
        /// <param name="option">echarts option</param>
        /// <returns>图片base64字符串</returns>
        [HttpPost]
        public string GetBase64String([FromBody] object option)
        {
            return GenBase64String(option);
        }

        /// <summary>
        /// 生成base64字符串
        /// </summary>
        /// <param name="option">echarts option</param>
        /// <returns>图片base64字符串</returns>
        private string GenBase64String(object option)
        {
            var service = ChromeDriverService.CreateDefaultService();
            var options = new ChromeOptions();
            options.AddArguments("--headless");
            options.AddArgument("--disable-gpu");
            options.AddArgument("--no-sandbox");
            var commandTimeout = TimeSpan.FromMinutes(1);
            using (ChromeDriver driver = new ChromeDriver(service, options, commandTimeout))
            {
                driver.Navigate().GoToUrl(Url.Action("GenImg", "Echarts", new { area = "Demo" }, Request.Scheme, Request.Host.Value));
                IJavaScriptExecutor scriptExecutor = driver;
                string echartsJS = 
                    "var myChart = echarts.init(document.getElementById('chartContainer'));" +
                    "myChart.on('finished',()=>{resolve(myChart.getDataURL({type:'png'}));});" +
                    $"var option = {JsonConvert.SerializeObject(option)};myChart.setOption(option);";
                string promiseJS = "let promise = new Promise((resolve,reject)=>{" +
                    echartsJS + "});" +
                    "var base64='';await promise.then((res)=>{base64 = res;});return base64;";
                return scriptExecutor.ExecuteScript(promiseJS).ToString();
            }
        }

解释一下,参数option就是echarts生成图表的option配置(注意设置animation=false,backgroundColor = "#fff")。核心方法是GenBase64String,这里面的代码不管是API还是其他的后台服务,都可以用。

Url.Action("GenImg", "Echarts", new { area = "Demo" }, Request.Scheme, Request.Host.Value)

这行代码,如果你没有新建文件夹作为Area, new { area = "Demo" }便可以不要。

里面用到了Promise,可以保证图片是渲染完成后再获取base64编码,这个是为了避免数据量巨大的时候,丢失数据,比如散点图,如果渲染没有完成,就执行到了获取base64编码的代码,点数丢失很严重。

最后也要避免将ChromeDriver作为单例使用,除非你能保证所有的请求或者调用按顺序执行并且都已经生成图片。像我写成接口,也许同时会有很多请求进来,如果是单例,driver.Navigate().GoToUrl可能会引发不可预测的结果。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值