SkiaSharp实战:5分钟搞定跨平台图表生成(支持导出PDF/SVG,含自动换行文本库推荐)

张开发
2026/4/20 15:54:35 15 分钟阅读

分享文章

SkiaSharp实战:5分钟搞定跨平台图表生成(支持导出PDF/SVG,含自动换行文本库推荐)
SkiaSharp实战5分钟搞定跨平台图表生成支持导出PDF/SVG含自动换行文本库推荐在业务系统开发中动态生成可视化图表是一个高频需求。无论是销售报表、运营数据看板还是实时监控仪表盘都需要后端或桌面应用能够快速生成专业级图表。传统方案往往依赖第三方图表库或前端渲染而SkiaSharp作为Google Skia图形库的.NET封装提供了从绘图到导出的全链路解决方案。本文将手把手带你用C#实现跨平台图表生成涵盖柱状图、折线图等基础图表绘制并重点解决导出PDF/SVG和文本自动换行两大核心痛点。1. 环境准备与基础绘图1.1 快速创建SkiaSharp项目通过NuGet安装核心库以Windows Forms为例Install-Package SkiaSharp -Version 2.88.3 Install-Package SkiaSharp.Views.WindowsForms Install-Package SkiaSharp.Extended基础绘图代码框架private void skControl1_PaintSurface(object sender, SKPaintSurfaceEventArgs e) { var canvas e.Surface.Canvas; canvas.Clear(SKColors.White); // 清空画布 // 创建画笔样式 var paint new SKPaint { Style SKPaintStyle.Fill, Color SKColors.Blue, IsAntialias true // 开启抗锯齿 }; // 绘制矩形柱状图基础元素 canvas.DrawRect(50, 200, 100, 150, paint); }1.2 核心绘图对象解析SkiaSharp的核心绘图元素包括对象作用典型配置参数SKCanvas绘图画布变换矩阵、裁剪区域SKPaint绘制样式颜色、笔触宽度、字体、特效SKPath复杂路径贝塞尔曲线、多边形路径SKBitmap位图操作像素读写、图像处理提示所有绘图操作应在PaintSurface事件中完成确保画面刷新时自动重绘2. 商业图表实战开发2.1 柱状图生成方案完整柱状图实现代码示例void DrawBarChart(SKCanvas canvas, float[] data) { float barWidth 40f; float startX 50f; float baseY 300f; // 绘制坐标轴 var axisPaint new SKPaint { Color SKColors.Black, StrokeWidth 2 }; canvas.DrawLine(startX, 50, startX, baseY, axisPaint); canvas.DrawLine(startX, baseY, startX 500, baseY, axisPaint); // 绘制数据柱 for (int i 0; i data.Length; i) { var height data[i] * 2; var rect SKRect.Create( x: startX (i * (barWidth 20)), y: baseY - height, width: barWidth, height: height); canvas.DrawRect(rect, new SKPaint { Color SKColor.Parse(#3498db), Style SKPaintStyle.Fill }); } }2.2 折线图实现技巧折线图关键实现逻辑计算数据点坐标创建SKPath连接各点添加数据标记点void DrawLineChart(SKCanvas canvas, float[] data) { var path new SKPath(); path.MoveTo(50, baseY - data[0] * 2); for (int i 1; i data.Length; i) { path.LineTo(50 i * 60, baseY - data[i] * 2); } canvas.DrawPath(path, new SKPaint { Color SKColors.Red, StrokeWidth 3, Style SKPaintStyle.Stroke }); // 绘制数据点 foreach (var point in path.Points) { canvas.DrawCircle(point, 5, new SKPaint { Color SKColors.White, StrokeWidth 2 }); } }3. 多格式导出实战3.1 PDF导出方案创建PDF画布并导出void ExportToPdf(string filePath, int width, int height) { using var stream new SKFileWStream(filePath); using var document SKDocument.CreatePdf(stream); // 开始新页面 var canvas document.BeginPage(width, height); // 在此canvas上绘制内容 DrawBarChart(canvas, new[] { 45f, 76f, 92f }); document.EndPage(); document.Close(); }3.2 SVG导出与矢量处理SVG导出特有的优势无限缩放不失真可直接用文本编辑器修改兼容现代浏览器void ExportToSvg(string filePath, int width, int height) { using var stream new SKFileWStream(filePath); using var canvas SKSvgCanvas.Create(SKRect.Create(width, height), stream); DrawLineChart(canvas, new[] { 30f, 45f, 28f, 60f }); }3.3 位图导出性能优化对于高频生成的场景建议使用内存流byte[] ExportToPng(int width, int height) { using var bitmap new SKBitmap(width, height); using var canvas new SKCanvas(bitmap); DrawBarChart(canvas, GetChartData()); using var image SKImage.FromBitmap(bitmap); using var data image.Encode(SKEncodedImageFormat.Png, 100); using var ms new MemoryStream(); data.SaveTo(ms); return ms.ToArray(); }4. 文本处理高级技巧4.1 自动换行解决方案集成SkiaTextRenderer库处理长文本Install-Package SkiaTextRenderer实际应用示例void DrawWrappedText(SKCanvas canvas, string text, SKRect bounds) { var textRenderer new TextBlockRenderer { MaxWidth bounds.Width, TextAlign TextAlignment.Left, Font new Font { Size 14, FamilyName Microsoft YaHei } }; textRenderer.AddText(text); textRenderer.Render(canvas, bounds.Left, bounds.Top); }4.2 多语言文本处理要点中文字体必须显式指定如SimSun、Microsoft YaHei混合语言文本建议统一使用支持Unicode的字体文字测量使用SKPaint.MeasureTextfloat MeasureText(string text, SKPaint paint) { var bounds new SKRect(); paint.MeasureText(text, ref bounds); return bounds.Width; }5. 性能优化与实战建议5.1 对象复用策略高频绘图场景应避免频繁创建对象// 推荐类级别缓存常用对象 private readonly SKPaint _axisPaint new SKPaint { Color SKColors.Black, StrokeWidth 2, IsAntialias true }; // 在绘图方法中直接复用 canvas.DrawLine(0, 0, 100, 100, _axisPaint);5.2 复杂图表优化方案当数据量较大时使用SKPicture录制绘图操作开启硬件加速通过GRContext分块渲染大数据集var recorder new SKPictureRecorder(); var recordingCanvas recorder.BeginRecording(SKRect.Create(800, 600)); // 执行绘图操作 DrawComplexChart(recordingCanvas); var picture recorder.EndRecording(); canvas.DrawPicture(picture); // 高效重放5.3 跨平台兼容性验证在不同平台需特别注意Linux环境需安装libSkiaSharp本地依赖WebAssembly需配置TrimmerRootAssemblyiOS/Android注意权限申请测试矩阵示例平台需验证项常见问题解决方案Windows高DPI支持设置SKGLControl.IgnorePixelScalingLinux字体渲染预装中文字体包macOS视网膜屏显示使用SKCanvasView替代传统控件

更多文章