none
Save Excel shape to EMF vector format RRS feed

  • Question

  • Hi, I get t a spreadsheet full of complicated drawings (shapes). I am trying to write a small utility to extract them to EMF. Everything works except the result turn out to be PNG images rather than EMF vector files. When I try to import them into other applications and resize, I lose resolution.

    Can anybody see what is wrong?

    using System;
    using System.Collections.Generic;
    using System.Drawing.Imaging;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.Office.Interop.Excel;

    namespace ShapeExtractor
    {
        class Program
        {
            [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); 
           
            static void Main(string[] args)
            {
                const int CF_ETAFILE = 14;

                try
                {
                    var xlApp = new Microsoft.Office.Interop.Excel.Application();
                    xlApp.WindowState = XlWindowState.xlMinimized;
                    xlApp.Visible = false;
                    Workbook wkBook = xlApp.Workbooks.Open("xyz.xlsx");

                    Worksheet iconSheet = wkBook.Sheets["Icons"];
                    if (iconSheet != null)
                    {
                        Shapes shapes = iconSheet.Shapes;
                        foreach (Shape shape in shapes)
                        {
                            shape.Copy();
                            if (OpenClipboard(IntPtr.Zero) &&
                                IsClipboardFormatAvailable(CF_ETAFILE) != 0)
                            {
                                IntPtr intPtr = GetClipboardData(CF_ETAFILE);
                                Metafile metaFile = new Metafile(intPtr, true);
                                CloseClipboard();
                                metaFile.Save(shape.Name + ".emf", ImageFormat.Emf);

                                Console.WriteLine(shape.Name);
                            }
                        }
                    }
                    wkBook.Close();
                    xlApp.Quit();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                }
            }
        }
    }


    Wednesday, March 21, 2018 7:01 PM

All replies

  • Hello Shan Wang BHI,

    I could reproduce your issue. As far as I know, Excel does not support to export shape as emf format. And, to be honestly, I'm not familiar with windows API. 

    Since Power Point support to export the shape as emf format. As a workaround, we could open a powerpoint file and copy shape from excel to power point temporary and then export it via Power Point.

    Here is the simply code.

     try
                {
                    var pptApp = new PPT.Application();
                    //pptApp.Visible = Microsoft.Office.Core.MsoTriState.msoFalse;
                    var slide=pptApp.Presentations.Add(Microsoft.Office.Core.MsoTriState.msoFalse).Slides.Add(1, PPT.PpSlideLayout.ppLayoutBlank);
                    dynamic shapeRange;
                    string shapeName = "";
    
                    var xlApp = new Microsoft.Office.Interop.Excel.Application();
                    xlApp.WindowState = Excel.XlWindowState.xlMinimized;
                    xlApp.Visible = false;
                    Excel.Workbook wkBook = xlApp.Workbooks.Open(@"C:\Users\v-guaxu\Desktop\TestFolder\111.xlsx");
                    
                    Excel.Worksheet iconSheet = wkBook.Sheets["Sheet1"];
                    if (iconSheet != null)
                    {
                        Excel.Shapes shapes = iconSheet.Shapes;
                        foreach (Excel.Shape shape in shapes)
                        {
                            shapeName = shape.Name;
                            shape.Copy();
                            shapeRange =slide.Shapes.PasteSpecial(PPT.PpPasteDataType.ppPasteDefault);
                            shapeRange.Export(@"C:\Users\v-guaxu\Desktop\TestFolder\" + shapeName + ".emf",
                                            5,Type.Missing,Type.Missing,1);
                            shapeRange.Delete();
                        }
                    }
                   
                    pptApp.Quit();
                    wkBook.Close();
                    xlApp.Quit();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

    Best Regards,

    Terry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, March 22, 2018 10:09 AM
  • Hello ,

    Has your original issue been resolved? If it has, I would suggest you mark the helpful reply as answer or provide your solution and mark as answer to close this thread. If not, please feel free to let us know your current issue.

    Best Regards,

    Terry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, March 30, 2018 9:14 AM