8

I have an image in a memory stream and I want to write this to an MS Excel document, the PIA only exposes the AddPicture method which takes a file path.

Is there away to add a picture without having to write the image to disc?

MSDN

http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.shapes.addpicture(v=office.14).aspx

4
  • 1
    can you add the code you have please? the few lines which add data to memorystream (picture format?) variable and the AddPicture or range/cell where you want the picture to be
    – user2299169
    Commented May 1, 2013 at 11:55
  • I don't really have any code for this, I'm looking to add this to an existing excel document generation process. Commented May 1, 2013 at 11:59
  • and you have a MemoryStream(ByteArrayImage), right?
    – user2299169
    Commented May 1, 2013 at 12:05
  • This still doesn't have a complete answer. The current answer doesn't replace the string to a filename.
    – j riv
    Commented May 25, 2018 at 4:58

1 Answer 1

7

Well, a bit of blind flying but assuming a thing or two about your code (e.g. the source of your stream, data type, etc) this could be a solution:
First, you need to create bitmap image data from the stream (which I assume is a byte stream, also assuming that the stream describes a bitmap image). There's a solution already for that here on Stack Overflow: Byte Array to Bitmap Image
I copy-paste the code from the solution:

int w= 100;
int h = 200;
int ch = 3; //number of channels (ie. assuming 24 bit RGB in this case)

byte[] imageData = new byte[whch]; //you image data here Bitmap bitmap = new Bitmap(w,h,PixelFormat.Format24bppRgb); BitmapData bmData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); IntPtr pNative = bmData.Scan0; Marshal.Copy(imageData,0,pNative,whch); bitmap.UnlockBits(bmData);
Also assuming you have an object for your workbook and the worksheet you are about to work with, something like this:
xlBook = (Excel.Workbook)objExcel.Workbooks.Add("");
xlSheet = (Excel.Worksheet)xlBook.Worksheets1;
xlSheet.Activate();
Now that you have a Bitmap-type variable, and a worksheet, all you need is to paste the image to the sheet:
System.Windows.Forms.Clipboard.SetDataObject(bitmap, false);
xlsRange = xlSheet.get_Range((Excel.Range)xlSheet.Cells[5, 15], (Excel.Range)xlSheet.Cells[5, 15]);
xlSheet.Paste(xlsRange, bitmap);

So the key is this guy here (instead of using "AddPicture"): Worksheet.Paste Method

Hope this helps!

7
  • Mark thanks for such a complete answer, will up vote when implemented Commented May 1, 2013 at 15:53
  • Unfortunately this won't work for me - the code is executing on a background (task pool) thread and therefore it's not an STA thread, Clipboard requires this. Commented May 2, 2013 at 13:51
  • tricky, you are. new rule. how about the evergreen "[threadobjvar].SetApartmentState(System.Threading.ApartmentState.STA);" ?
    – user2299169
    Commented May 2, 2013 at 19:52
  • the thread state has already been set, because it's a background thread, and attempting to set it again barfs Commented May 3, 2013 at 7:08
  • for the above solution you need to create a new thread then and start -inside the current/running one-
    – user2299169
    Commented May 3, 2013 at 7:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.