将excel范围导出到指定位置的EMF文件

时间:2015-03-02 00:22:59

标签: c# excel range vsto

我无法将我的范围导出到emf文件中。它会被复制到剪贴板,因为我可以在抛出异常后粘贴它:

  

类型' System.NullReferenceException'的例外情况发生在   N1Narrator.dll但未在用户代码中处理   information:对象引用未设置为对象的实例。   < - 引用' img'

这是我的代码:

if (intersectRange != null && name.RefersToRange.Cells.Count > 1)
{                            
       name.RefersToRange.CopyPicture(Excel.XlPictureAppearance.xlScreen, Excel.XlCopyPictureFormat.xlPicture);

      const int CF_ETAFILE = 14;
                                IntPtr intptr;

                                System.Drawing.Imaging.Metafile myMetaFile = null;
                                if (ClipboardFunctions.OpenClipboard(IntPtr.Zero))
                                {
                                    if (ClipboardFunctions.IsClipboardFormatAvailable(CF_ETAFILE) != 0)
                                    {
                                        intptr = ClipboardFunctions.GetClipboardData(CF_ETAFILE);
                                        myMetaFile = new Metafile(intptr, true);
                                        ClipboardFunctions.CloseClipboard();
                                        myMetaFile.Save(@"C:\Users\Nick\AppData\Local\Temp\Narrative1\N1Appraisal\ExcelTables\testtable.emf", ImageFormat.Emf);
                                    }
                                }  

}

我也在剪贴板上查看了DataObject(),但无济于事。我不想使用Chart方法,它太慢了。

2 个答案:

答案 0 :(得分:0)

假设问题是使用Image数据类型从剪贴板保存EMF矢量图像而不是位图,您可以use this code

//using System.Runtime.InteropServices;  
public class ClipboardFunctions  
{  
    [DllImport("user32.dll", EntryPoint = "OpenClipboard", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]  
    public static extern bool OpenClipboard(IntPtr hWnd);  

    [DllImport("user32.dll", EntryPoint = "EmptyClipboard", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]  
    public static extern bool EmptyClipboard();  

    [DllImport("user32.dll", EntryPoint = "SetClipboardData", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]  
    public static extern IntPtr SetClipboardData(int uFormat, IntPtr hWnd);  

    [DllImport("user32.dll", EntryPoint = "CloseClipboard", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]  
    public static extern bool CloseClipboard();  

    [DllImport("user32.dll", EntryPoint = "GetClipboardData", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]  
    public static extern IntPtr GetClipboardData(int uFormat);  

    [DllImport("user32.dll", EntryPoint = "IsClipboardFormatAvailable", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]  
    public static extern short IsClipboardFormatAvailable(int uFormat);  
}  

private void button1_Click(object sender, EventArgs e)  
{  
    const int CF_ETAFILE = 14;  
    IntPtr intptr;  

    System.Drawing.Imaging.Metafile myMetaFile = null;  
    if (ClipboardFunctions.OpenClipboard(this.Handle))  
    {  
        if (ClipboardFunctions.IsClipboardFormatAvailable(CF_ETAFILE) != 0)  
        {  
            intptr = ClipboardFunctions.GetClipboardData(CF_ETAFILE);  
            myMetaFile = new System.Drawing.Imaging.Metafile(intptr, true);  
            ClipboardFunctions.CloseClipboard();  
            myMetaFile.Save(@"c:\test.jpg", ImageFormat.Jpeg);  
        }  
    }  
} 

这是一个类似的question/answer

如果您不确定Excel中的图片格式是什么,请尝试拨打Clipboard.GetImage()

,而不是拨打Clipboard.GetDataObject()

这将返回一个IDataObject,您可以通过调用dataObject.GetFormats()来进行查询。 GetFormats()返回Clipboard对象支持的类型格式 - 可以使用更精确的格式来提取数据(但我很确定Excel确实使用EMF作为图形)。

答案 1 :(得分:0)

原谅我在Stackoverflow评论中缺乏技能。

sel.CopyPicture(Appearance: Excel.XlPictureAppearance.xlScreen, Format: Excel.XlCopyPictureFormat.xlBitmap);
var image = System.Windows.Forms.Clipboard.GetImage();

此代码适用于Excel 2013插件。请注意我使用的是xlBitmap而不是xlPicture。这符合您的要求吗?或者我也会尝试使用xlPicture。