首页 前端知识 .NetCore后台生成Echarts图表(chromedriver Selenium.WebDriver)

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

2024-04-03 12:04:38 前端知识 前端哥 56 224 我要收藏

有些需求比如生成的报告,需要添加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可能会引发不可预测的结果。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/4439.html
标签
selenium
评论
发布的文章

java解析超大json文件数据

2024-04-19 21:04:10

头歌-JavaScript基础

2024-04-19 21:04:54

C#Json序列化及反序列化

2024-04-19 21:04:40

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!