2015-03-02 3 views
0

У меня возникли проблемы с доставкой моего диапазона в файл emf. Он копируется в буфер обмена, потому что я могу вставить его после того, как исключение:Экспорт диапазона excel в файл EMF в указанном месте

Исключение типа «System.NullReferenceException» произошло в N1Narrator.dll, но не был обработан в коде пользователя Дополнительная информация : В экземпляре объекта не задана ссылка на объект. < --referencing '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, это будет слишком медленно.

+0

Какой буфер обмена вы используете? System.Windows или System.Windows.Forms? – ShipOfTheseus

+0

System.Windows.Forms – Drew2127

+0

О, боже, это сработало, я был идиотом и забыл сменить XLBitmap на XLPicture. Большое вам спасибо. – Drew2127

ответ

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 для графиков).

+0

Я отредактировал ваш вопрос соответственно. Является 'Image' из пространства имен System.Drawing (https://msdn.microsoft.com/en-us/library/system.drawing.image%28v=vs.110%29.aspx) или какого-либо типа, который вы создали в проекте N1Narrator? Вы попробовали мой метод? –

+0

Спасибо, Джереми, извиняюсь, я новичок в этом. Я попробовал ваш метод, но я не использую кнопку, так что я могу разместить в аргументе в .opensclipboard, если условие? Также я попробовал IDataObject, я редактирую сообщение, чтобы показать как IDataObject, так и ваш метод. Я прокомментировал код IDataObject. – Drew2127

0

Простите меня за недостаток навыков в комментариях Stackoverflow.

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

Этот код отлично подходит для меня в приложении Excel 2013. Заметьте, что вместо xlPicture я использую xlBitmap. Соответствует ли это вашим требованиям? Или я попробую с xlPicture.

+0

Выполняется ваш код, а затем я сохраняю изображение var в каталоге. Откройте изображение в краске, и они пусты, с теми же размерами диапазона, что и появляется. Я пробовал «bmp» и «emf» – Drew2127

+0

1) Обратите внимание, что ответ Джереми - правильный ответ для xlPicture. Мой код работает только для xlBitmap. 2) image.Save (@ "C: \ temp \ test.bmp", System.Drawing.Imaging.ImageFormat.Bmp); ---- Это отлично работает для меня, чтобы сохранить изображение как BMP. – ShipOfTheseus

+0

Обратите внимание: переменная изображения, которую я использую, имеет тип System.Drawing.Image. – ShipOfTheseus

Смежные вопросы