如何在C#代码中将Highcharts图表保存为SVG到本地磁盘?
如何在C#代码中生成Highcharts的SVG并保存到本地?
我现在用下面的C#代码生成Highcharts图表并嵌入HTML页面,想同时把图表以SVG格式保存到本地磁盘,方便后续嵌入PDF文件。但找到的示例大多是JavaScript实现的,请问怎么在这段C#代码里实现这个功能?
视图组件代码:
@using Highsoft.Web.Mvc.Charts @using Highsoft.Web.Mvc.Charts.Rendering @using System.Collections @{ List<string> values = new List<string>(); Model.columnSeries.ForEach(u => values.Add(u.Name.ToString())); var chartOptions = new Highcharts { Boost = { UseGPUTranslations = true }, Title = new Title { Text = @Model.Title }, Subtitle = new Subtitle { Text = @Model.SubTitle }, XAxis = new List<XAxis> { new XAxis { Categories = values, AllowDecimals = false, Labels = new XAxisLabels { Rotation = -45 //Formatter = "formatXAxis" } } }, YAxis = new List<YAxis> { new YAxis { Title = new YAxisTitle { Text = @Model.YaxisLabel }, Labels = new YAxisLabels { //Formatter = "formatYAxis" } } }, Tooltip = new Tooltip { PointFormat = "{series.name}: <b>{point.y:.0f}</b>" }, PlotOptions = new PlotOptions { Column = new PlotOptionsColumn { } }, Series = new List<Series> { new ColumnSeries { Data = @Model.columnSeries } } }; chartOptions.ID = "Services"; var renderer = new HighchartsRenderer(chartOptions); } @Html.Raw(renderer.RenderHtml())
视图中调用组件的代码:
@await Component.InvokeAsync("ServiceChart", new {clientId = Model.ClientId, startDate = Model.StartDate, endDate = Model.EndDate})
解决方案
针对你的场景,有两种可靠的实现方式,直接落地可用:
方式一:服务端用无头浏览器渲染(推荐,不依赖外部服务)
利用PuppeteerSharp(.NET版无头Chrome)加载Highcharts配置并完成渲染,直接获取SVG内容保存:
- 安装依赖:在项目中安装
PuppeteerSharpNuGet包 - 将图表配置逻辑移到后台(组件类/控制器),添加以下代码:
using Newtonsoft.Json; using PuppeteerSharp; using System.IO; // 1. 构造Highcharts配置(和视图内逻辑一致) List<string> values = new List<string>(); columnSeries.ForEach(u => values.Add(u.Name.ToString())); var chartOptions = new Highcharts { Boost = { UseGPUTranslations = true }, Title = new Title { Text = model.Title }, Subtitle = new Subtitle { Text = model.SubTitle }, XAxis = new List<XAxis> { new XAxis { Categories = values, AllowDecimals = false, Labels = new XAxisLabels { Rotation = -45 } } }, YAxis = new List<YAxis> { new YAxis { Title = new YAxisTitle { Text = model.YaxisLabel } } }, Tooltip = new Tooltip { PointFormat = "{series.name}: <b>{point.y:.0f}</b>" }, PlotOptions = new PlotOptions { Column = new PlotOptionsColumn() }, Series = new List<Series> { new ColumnSeries { Data = columnSeries } } }; // 2. 序列化配置为JSON string chartConfigJson = JsonConvert.SerializeObject(chartOptions); // 3. 构造包含Highcharts的HTML模板 string htmlTemplate = $@" <!DOCTYPE html> <html> <head> <script src=""https://code.highcharts.com/highcharts.js""></script> </head> <body> <div id=""chart-container"" style=""width: 800px; height: 600px;""></div> <script> var chart = Highcharts.chart('chart-container', {chartConfigJson}); </script> </body> </html>"; // 4. 启动无头浏览器渲染并获取SVG await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision); using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }); using var page = await browser.NewPageAsync(); await page.SetContentAsync(htmlTemplate); // 等待渲染完成,执行JS获取SVG string svgContent = await page.EvaluateExpressionAsync<string>("chart.getSVG()"); // 5. 保存到本地磁盘 string savePath = Path.Combine(Environment.CurrentDirectory, "chart-output.svg"); await File.WriteAllTextAsync(savePath, svgContent);
方式二:前端生成SVG后传给后端保存
如果不想在服务端处理渲染,可在前端页面加载完成后,用Highcharts的JS API获取SVG,再通过AJAX传给后端接口保存:
在视图末尾添加JS代码:
<script> // 延迟等待图表完全渲染 setTimeout(() => { var targetChart = Highcharts.charts.find(chart => chart.renderTo.id === 'Services'); if (targetChart) { const svg = targetChart.getSVG(); // 发送SVG到后端接口 fetch('/SaveChartSvg', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ svgContent: svg }) }); } }, 1000); </script>后端添加保存接口:
[HttpPost] public async Task<IActionResult> SaveChartSvg([FromBody] SvgRequest model) { string savePath = Path.Combine(Environment.CurrentDirectory, "chart-output.svg"); await File.WriteAllTextAsync(savePath, model.SvgContent); return Ok(); } // 对应的请求模型类 public class SvgRequest { public string SvgContent { get; set; } }
内容的提问来源于stack exchange,提问作者user2005143
相关产品推荐
相关产品推荐

