Search code examples
c#.netexcelinterop

How can I copy a range in excel and paste it as an image using c#?


I want to select a range in a sheet and paste it into another as an image, using Interop.

It is easy to do using the Excel UI, just right-click the cell then paste special > image.

How to do in excel

I tried to do something similar to this VBA macro, but I could not find any method similar to ActiveSheet.Pictures.Paste.Select.

    Range("C5:U22").Select
    Selection.Copy
    Range("I4").Select
    Sheets("Sheet2").Select
    Range("E7").Select
    ActiveSheet.Pictures.Paste.Select

I also tried to copy the range and get the clipboard data as an image using range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);, and then save it to a file and copy the file back to Excel. But it did not work as the image file was empty. (I know that the performance of this solution would not be good, but I could not think of anything else.)

range.CopyPicture(XlPictureAppearance.xlScreen, XlCopyPictureFormat.xlBitmap);
string imagePath = Path.Combine(stringTmpDirPath, "image.png");
SaveClipboardImageToFile(imagePath);

private static void SaveClipboardImageToFile(string filePath)
{
    BitmapSource image = Clipboard.GetImage();

    if (image == null) return;
    using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
    {
        BitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(image));
        encoder.Save(fileStream);
    }
}

Reference


Solution

  • The Pictures is defined in Worksheet class. In Object Browser the 'Show Hidden Members' needs to be activated to be able to see the Pictures.

    enter image description here

    So then in VBA the following macro will copy the range:

    Dim source As Range
    Set source = Sheets("Sheet1").Range("A1:C10")
    
    source.CopyPicture
    
    Dim target As Worksheet
    Set target = Worksheets("Sheet2")
    target.Range("A1").Select ' Here the picture is going to be pasted
    
    Dim pics As Pictures
    Set pics = target.Pictures
    pics.Paste
    

    Which them in C# could look something like this:

    using Excel = Microsoft.Office.Interop.Excel;
    
    var excelApp = new Excel.Application
    {
        Visible = true
    };
    
    Excel.Workbook wrb = excelApp.Workbooks.Add();
    Excel.Worksheet wks1 = wrb.Worksheets.Add();
    wks1.Name = "Source";
    Excel.Range sourceRange = wks1.Range[wks1.Cells[1, 1], wks1.Cells[10, 10]];
    sourceRange.Value = "Text-123";
    sourceRange.CopyPicture();
    
    Excel.Worksheet wks2 = wrb.Worksheets.Add(After: wks1);
    wks2.Name = "Target";
    ((Excel.Range)wks2.Cells[1, 1]).Select(); // Here the picture is going to be pasted
    Excel.Pictures pics = wks2.Pictures();
    pics.Paste();