【问题标题】:How to properly export chart as picture from WinForms to Excel?如何正确地将图表作为图片从 WinForms 导出到 Excel?
【发布时间】:2021-06-16 16:17:55
【问题描述】:

我需要一种稳定的方法将 System.Windows.Forms.DataVisualization.Charting 对象作为图片导出到 Excel。首先我需要说我曾经有一个稳定的解决方案,随着 Win 10 的升级和更新逐步降级。我的场景是我有一个带有多个图表的 WinForms 面板。当用户单击一个按钮时,一个过程开始在此面板中循环图表,将它们作为图片一张一张地复制到剪贴板,然后再一张一张地粘贴到 Excel 工作簿。下面给出的代码非常简化。

在 Win 7 下,以下代码可以作为魅力:

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))

但是在安装 Win 10 之后,稳定性降低了,粘贴部分开始失败,出现臭名昭著的异常 0x800A03EC。例如,如果面板中有 50 个图表,则在 80% 的情况下,一两个图表会失败。这就是为什么我修改了我的代码并放置了 Try - Catch 块。事实上 2 个这样的块,因为如果第一次尝试失败再试一次,因为我不喜欢 Excel 导出中缺少图表。这个修改后的解决方案适用于 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

最近可能在 Win 10 更新后复制部分 (Clipboard.SetDataObject) 开始严重失败,出现异常“请求的剪贴板操作未成功”。这就是为什么我用重试时间、超时等扩展了 SetDataObject 参数,但这并没有带来改进。然后我再次实现了 2 个块 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

【问题讨论】:

    标签: excel vb.net charts


    【解决方案1】:

    我强烈建议不要使用剪贴板将图表导出到 Excel,因为它在我的问题中描述的稳定性不可预测,而且在操作过程中不得触摸剪贴板。更好的方法是将图表对象保存到硬盘,然后插入 Excel 工作表。这似乎是一个稳定的解决方案,经过多次尝试,我没有丢失一张图表。一个非常简化的解决方案如下所示。第一行将图像保存到硬盘,第二行将其插入 Excel。

    ch.SaveImage(My.Application.Info.DirectoryPath & "\ch" + chartSuffix.ToString + ".png", System.Drawing.Imaging.ImageFormat.Png)
    
    xlWorkSheet.Shapes.AddPicture(My.Application.Info.DirectoryPath & "\ch" + chartSuffix.ToString + ".png", False, True, 0, row, -1, -1)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 2021-05-26
      相关资源
      最近更新 更多