如何将WinForms Charting图表稳定导出为图片并粘贴到Excel
我需要一套稳定的实现方案,把System.Windows.Forms.DataVisualization.Charting对象以图片形式导出到Excel。此前我有一套长期稳定运行的方案,但随着Win10版本迭代和后续系统补丁推送,整体稳定性逐步下降。
我的实际使用场景:在WinForms面板中放置多个图表,用户点击导出按钮后,程序遍历面板内所有图表,将每个图表转成图片暂存到剪贴板,再逐个粘贴到Excel工作簿中。下文给出的所有代码均为简化版本。
Win7 环境下的原始稳定方案
在Win7系统中,以下代码运行效果完全符合预期:
Dim stream As New System.IO.MemoryStream() chart.SaveImage(stream, Imaging.ImageFormat.Png) Dim bmp As New Bitmap(stream) Clipboard.SetDataObject(bmp) xlWorkSheet.Paste(xlWorkSheet.Range("A" + row.ToString))
迁移Win10后的第一阶段故障
升级到Win10后,原有方案稳定性下降,粘贴环节开始频繁抛出0x800A03EC异常。比如面板内加载50个图表时,80%的导出流程中会有1-2个图表粘贴失败。
为了避免导出的Excel缺失图表,我给代码增加了两层Try-Catch重试逻辑:首次粘贴失败时自动重试一次,修改后的方案可用率达99.5%,基本满足使用要求:
Dim stream As New System.IO.MemoryStream() ch.SaveImage(stream, Imaging.ImageFormat.Png) Dim bmp As New Bitmap(stream) Clipboard.SetDataObject(bmp) Try xlWorkSheet.Paste(xlWorkSheet.Range("A" + row.ToString)) Catch Try xlWorkSheet.Paste(xlWorkSheet.Range("A" + row.ToString)) Catch End Try End Try
近期Win10系统更新后的新故障
大概率是最近一次Win10系统更新后,故障点转移到了剪贴板写入环节:Clipboard.SetDataObject开始频繁抛出Requested Clipboard operation did not succeed异常。我已经为SetDataObject补充了重试次数、超时时长等参数,问题毫无改善;后续即便嵌套两层Try-Catch做兜底,也无法完全覆盖异常,最终只能在Excel对应图表位置输出提示文本,告知用户手动完成粘贴。
注:导出流程运行时,全程无用户操作占用剪贴板或Excel,不存在用户侧的干扰因素。
当前的兜底代码如下:
Dim stream As New System.IO.MemoryStream() ch.SaveImage(stream, Imaging.ImageFormat.Png) Dim bmp As New Bitmap(stream) Try Clipboard.SetDataObject(bmp, False, 16, 100) Catch Try Clipboard.SetDataObject(bmp, False, 16, 100) Catch errorClip = True End Try End Try If errorClip = False Then Try xlWorkSheet.Paste(xlWorkSheet.Range("A" + row.ToString)) Catch Try xlWorkSheet.Paste(xlWorkSheet.Range("A" + row.ToString)) Catch End Try End Try Else xlWorkSheet.Range("A" + row.ToString).Value = "Error copying chart. Paste it manually." End If
内容的提问来源于stack exchange,提问作者Ivaylo

