Excel 2003 Windows窗体剪贴板DataObject

时间:2010-10-29 19:38:00

标签: .net clipboard office-interop

我正在尝试访问复制到剪贴板中的Excel 2003图表。

图表图像可以很好地粘贴到mspaint或wordpad中。

问题是我在System.Windows.Forms.Clipboard对象上看不到图表的数据。

我已阅读以下帖子:

Pasting Image from Excel 2003 Clipboard

在我的特定场景中,PNG,JFIF或GIF格式在剪贴板DataObject上显示为格式的唯一时间是当我转到Excel剪贴板管理器(在Excel应用程序中)并再次重新复制图表时开。

也就是说,如果我清除剪贴板,打开Excel 2003,创建一个图表,右键单击它,点击Copy,然后检查Clipboard.GetDataObject()。GetFormats(),我看到的只有:

Clipboard.GetDataObject().GetFormats()
{string[6]}
    [0]: "EnhancedMetafile"  // is null
    [1]: "Embed Source"  // is a MemoryStream of about 10KB which seems to be an OLE representation for the whole workbook
    [2]: "Object Descriptor" // a very short (10 bytes) MemoryStream
    [3]: "Link Source" // a very short (10 bytes) MemoryStream
    [4]: "Link Source Descriptor"  // a very short (10 bytes) MemoryStream
    [5]: "Link"  // null 

如果我在编辑>下打开Excel剪贴板管理器Office剪贴板然后复制相同的图表,即使Clipboard.ContainsImage()返回false,我看到:

Clipboard.GetDataObject().GetFormats()
{string[10]}
    [0]: "Office Drawing Shape Format"
    [1]: "MetaFilePict"
    [2]: "EnhancedMetafile"
    [3]: "PNG+Office Art"  // can read with Image.FromStream
    [4]: "JFIF+Office Art"  // can read with Image.FromStream
    [5]: "GIF+Office Art"  // can read with Image.FromStream
    [6]: "PNG" // can read with Image.FromStream
    [7]: "JFIF" // can read with Image.FromStream
    [8]: "GIF" // can read with Image.FromStream
    [9]: "ActiveClipBoard"

并且可以将任何一种图像格式作为MemoryStream而没有任何问题。

我无需打开Excel剪贴板管理器即可使用此功能。它在2007年和2010年运行良好(为方便起见,它还包括一个常规的Bitmap格式,以便Clipboard.ContainsImage()返回true)...

我已经在多个工作站上验证了这种行为。

我认为接下来的步骤可能是获取本地System.Runtime.InteropServices.ComTypes.IDataObject或者更糟糕的是获得运行Excel实例的COM对象的句柄......但我宁愿没有到。

感谢您的帮助......

1 个答案:

答案 0 :(得分:1)

哇....好吧,我希望这有助于其他人......

我有随机的想法尝试WPF剪贴板对象(System.Windows.Clipboard),然后再直接使用OLE32.dll ....

罗,看哪......

System.Windows.Clipboard.GetDataObject().GetFormats()
{string[7]}
    [0]: "EnhancedMetafile"
    [1]: "System.Drawing.Imaging.Metafile"
    [2]: "Embed Source"
    [3]: "Object Descriptor"
    [4]: "Link Source"
    [5]: "Link Source Descriptor"
    [6]: "Link"

果然:

System.Windows.Clipboard.GetData(System.Windows.Clipboard.GetDataObject().GetFormats()[0])
    {System.Drawing.Imaging.Metafile}

等......

((Image)System.Windows.Clipboard.GetData(System.Windows.Clipboard.GetDataObject().GetFormats()[0])).Save("C:\\test1.jpg")
    base {System.Drawing.Image}: {System.Drawing.Imaging.Metafile}

像魔法一样......

我怀疑直接使用OLE32.dll也会有效,因为无论如何Windows Forms和WPF的剪贴板API都会去那里......