none
Get Image shape from Excel to BitmapImage RRS feed

  • Question

  • Hi everyone,

    Currently, I have a task which will read an excel file (which contains a lots small resized images ), then my App will get each image and show a bigger one.

    My simple plan is get image shapes in the excel and convert them to BitmapImage, then set Source for Image control.

    I was able to get shapes, but stuck at show them on my App ( convert them to BitmapImage, etc. )

    Is the anyway I can achieve this ?

    Thanks for reading !

    Friday, June 15, 2018 11:04 AM

Answers

  • My solution so far is get all the shapes in excel, then use Shape.Copy() to move data into Clipboard, then finally use Clipboard.GetImage() to get BitmapSource, which viewable on Image.

    private void getExcel_Click(object sender, RoutedEventArgs e)
            {
                Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
                dlg.DefaultExt = ".xlsx";
                bool? result = dlg.ShowDialog();
    
                if (result != true) return;
    
                string workbookPath = dlg.FileName;
    
                Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
                Workbook excelWorkbook = excelApp.Workbooks.Open(workbookPath, Type.Missing, false, Type.Missing, Type.Missing, Type.Missing,
                   false, XlPlatform.xlWindows, Type.Missing,
                   true, false, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                Worksheet sheet = excelWorkbook.Sheets["Sheet1"] as Worksheet;
    
                if (sheet == null) return;
    
                var shapes = new List<Microsoft.Office.Interop.Excel.Shape>();
                for (int i = 1; i <= sheet.Shapes.Count; i++)
                {
                    var shape = sheet.Shapes.Item(i);
                    shapes.Add(shape);
                }
    
                _index = 0;
                _listImage.Clear();
                foreach (var shape in shapes)
                {
                    if (shape.Width < 500)
                        shape.ScaleWidth(4f, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft);
                    shape.Copy();
                    shape.ScaleWidth(0.25f, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft);
                    var image = Clipboard.GetImage();
                    _listImage.Add(image);
                }
                if (shapes.Count > 0)
                {
                    preview.Source = _listImage[0];
                }
    
                excelWorkbook.Save();
                excelWorkbook.Close();
                excelApp.Quit();
                
                
                {
                    if (sheet != null)
                        Marshal.ReleaseComObject(sheet);
    
                    if (excelWorkbook != null)
                        Marshal.ReleaseComObject(excelWorkbook);
                    if (excelApp != null)
                        Marshal.ReleaseComObject(excelApp);
                    excelApp = null;
                }
            }
    I wonder if there is a better solution.

    • Proposed as answer by Wouter Defour Monday, June 18, 2018 8:07 AM
    • Marked as answer by minh91a1 Tuesday, July 3, 2018 8:06 AM
    Sunday, June 17, 2018 4:07 PM

All replies

  • My solution so far is get all the shapes in excel, then use Shape.Copy() to move data into Clipboard, then finally use Clipboard.GetImage() to get BitmapSource, which viewable on Image.

    private void getExcel_Click(object sender, RoutedEventArgs e)
            {
                Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
                dlg.DefaultExt = ".xlsx";
                bool? result = dlg.ShowDialog();
    
                if (result != true) return;
    
                string workbookPath = dlg.FileName;
    
                Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
                Workbook excelWorkbook = excelApp.Workbooks.Open(workbookPath, Type.Missing, false, Type.Missing, Type.Missing, Type.Missing,
                   false, XlPlatform.xlWindows, Type.Missing,
                   true, false, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
                Worksheet sheet = excelWorkbook.Sheets["Sheet1"] as Worksheet;
    
                if (sheet == null) return;
    
                var shapes = new List<Microsoft.Office.Interop.Excel.Shape>();
                for (int i = 1; i <= sheet.Shapes.Count; i++)
                {
                    var shape = sheet.Shapes.Item(i);
                    shapes.Add(shape);
                }
    
                _index = 0;
                _listImage.Clear();
                foreach (var shape in shapes)
                {
                    if (shape.Width < 500)
                        shape.ScaleWidth(4f, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft);
                    shape.Copy();
                    shape.ScaleWidth(0.25f, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromTopLeft);
                    var image = Clipboard.GetImage();
                    _listImage.Add(image);
                }
                if (shapes.Count > 0)
                {
                    preview.Source = _listImage[0];
                }
    
                excelWorkbook.Save();
                excelWorkbook.Close();
                excelApp.Quit();
                
                
                {
                    if (sheet != null)
                        Marshal.ReleaseComObject(sheet);
    
                    if (excelWorkbook != null)
                        Marshal.ReleaseComObject(excelWorkbook);
                    if (excelApp != null)
                        Marshal.ReleaseComObject(excelApp);
                    excelApp = null;
                }
            }
    I wonder if there is a better solution.

    • Proposed as answer by Wouter Defour Monday, June 18, 2018 8:07 AM
    • Marked as answer by minh91a1 Tuesday, July 3, 2018 8:06 AM
    Sunday, June 17, 2018 4:07 PM
  • Hello mih91a1,

    Does your current solution have any issue to run?

    Excel Object Model does not provide the function to export a shape as a picture directly. Usually, we copy a shape to a newly created chart and then use Chart.Export function to export the chart with the shape as a picture file.

    However, I do not think the solution is better than yours. You need do more copy and paste work and the exported shapes will have a white background. 

    Surely, if you do need a Bitmap Image, you could take the solution. Please try to refer to below to do this work. Please feel to let us know if you need more help in C# code.

    https://stackoverflow.com/questions/18232987/export-pictures-from-excel-file-into-jpg-using-vba

    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.

    Monday, June 18, 2018 7:51 AM