سؤال

I have some code that i want to convert an excel spread sheet to html so i can use it as the body of a email.

        Excel.Application excel = new Excel.Application();
        Excel.Workbook workbook = excel.Workbooks.Open(Properties.Settings.Default.FileToSend);

        //Save the workbook to Memory Stream in HTML format
        MemoryStream ms = new MemoryStream();

        // This is the line i have an error on
        workbook.SaveAs(ms, Excel.XlFileFormat.xlHtml); 

        //Seek MemoryStream position to 0
        ms.Position = 0;

        //Define a StreamReader object with the above MemoryStream
        StreamReader sr = new StreamReader(ms);

        //Load the saved HTML from StreamReader now into a string variable
        string strHtmlBody = sr.ReadToEnd();

This is the line i get the error on

        // This is the line i have an error on
        workbook.SaveAs(ms, Excel.XlFileFormat.xlHtml); 

I get this error Cannot access 'System.IO.MemoryStream'.

The exception is

System.Runtime.InteropServices.COMException was unhandled
HelpLink=xlmain11.chm
HResult=-2146827284
Message=Cannot access 'System.IO.MemoryStream'.
Source=Microsoft Excel
ErrorCode=-2146827284
StackTrace:
   at Microsoft.Office.Interop.Excel._Workbook.SaveAs(Object Filename, Object FileFormat, Object Password, Object WriteResPassword, Object ReadOnlyRecommended, Object  \ CreateBackup, XlSaveAsAccessMode AccessMode, Object ConflictResolution, Object AddToMru, Object TextCodepage, Object TextVisualLayout, Object Local)
   at Auto_KPI_Email.Program.sendExcel() in E:\My Documents\Visual Studio 2010\Projects\Auto KPI Email\Auto KPI Email\Program.cs:line 71
   at Auto_KPI_Email.Program.Main(String[] args) in E:\My Documents\Visual Studio 2010\Projects\Auto KPI Email\Auto KPI Email\Program.cs:line 19
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()
InnerException: 

Any advice?

هل كانت مفيدة؟

المحلول

As @GrantWinney pointed out in his answer, you cannot save a workbook to a MemoryStream using the available API.

Your best solution is to output the HTML to a temporary location and then read the result back in.

Excel.Application excel = new Excel.Application();
Excel.Workbook workbook = excel.Workbooks.Open(Properties.Settings.Default.FileToSend);

var temporaryFilepath = Path.ChangeExtension(Path.GetTempFileName(), ".html");
workbook.SaveAs(temporaryFilepath, Excel.XlFileFormat.xlHtml);

var result = File.ReadAllText(temporaryFilepath);

Not as elegant as keeping it in memory, however when integrating with other programs it is sometimes the only solution.

نصائح أخرى

According to MSDN, and the stacktrace you posted, the first parameter is a file name (string). The reason it accepts your MemoryStream (or anything else you feel like passing to it) is because the parameter type is an object. At runtime though, it expects a string.

Filename Optional Object. A string that indicates the name of the file to be saved. You can include a full path; if you don't, Microsoft Excel saves the file in the current folder.

I don't see any parameter in that SaveAs method that would accept a stream. Looks like if you want to save your workbook, you'll have to save it to disk.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top