When trying to stream back the resulting byte-array of the GetWorkbook() from ASP.NET, you may run into this issue. I just ran into it yesterday and today I saw a post about it in the Excel Services forums, so I thought I'd explain what's probably going on.
(I can't answer on the forums because the freaking thing is again in that quasi-logged out state where I can't do anything or answer questions. SO annoying.)
If you open the file you streamed in a binary editor (or notepad for that matter), you will probably see at the bottom some HTML text. That text is there because ASP.NET, once it finished outputting the binary contents of the workbook via the Response.OutputStream.Write(...) method, continued to write HTML into the file. That causes "garbage" to be written to the end of the file which in turn causes Excel to show the error at the top of this post.
To solve the issue, call Request.EndResponse() when you finish writing the binary data into the Response.OutputStream object. That will cause ASP.NET to stop dead in its tracks and return only the data you have written.
Now, that "Stop dead" in its track thing is the important bit. What actually happens is that Request.EndResponse actually injects a ThreadAbortException into the thread, causing the call to exit completely. The issue I was having is related to that.
As part of my rendering code, I had a path that would write to the HTML any error that occurred. This helps with debugging issues with the page that is hosted by SharePoint, which is a fun thing to do. So my code looked something like this:
// Do stuff..
catch (Exception ex)
Page.Response.OutputStream.Write("An error occurred: " + ex.ToString());
The net result of this is that each of my produced Excel files had the .ToString() of a ThreadAbortException tacked at the end.
Catching ThreadAbort specifically and not outputting anything there did the trick and produced proper files.
(Thanks go to Boaz who helped me figure out what was wrong with the files)