使用OpenXML在内存中发送电子邮件附件

时间:2009-06-25 13:48:24

标签: email openxml

我有一个使用OpenXML 2构建的Excel文件,我想将其作为电子邮件附件发送。 e.g。

    System.IO.MemoryStream stream = new System.IO.MemoryStream();
    SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
    AddParts(package); //created using document reflector

使用

将电子表格保存到临时文件
stream.WriteTo(new System.IO.FileStream(@"c:\test.xlsx", System.IO.FileMode.Create));

工作正常。但是尝试直接将电子邮件附件作为电子邮件附件发送失败 - 当我这样做时,只需在电子邮件中附加一个空文件

System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(stream, "MobileBill.xlsx", "application/vnd.ms-excel");

有人知道怎么做吗?

4 个答案:

答案 0 :(得分:5)

好的,我通过一些努力得到了这个。要创建流:

MemoryStream stream = new MemoryStream();

using (SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
{
  Excel.CreateSpreadsheet(package, Excel_Methods.CreateSpotQuoteOut(), true);
}

stream.Seek(0, SeekOrigin.Begin);

System.Net.Mail.Attachment attach = new System.Net.Mail.Attachment(stream, "spreadsheet.xlsx");

attach.ContentDisposition.CreationDate = DateTime.Now;
attach.ContentDisposition.ModificationDate = DateTime.Now;
attach.ContentDisposition.Inline = false;
attach.ContentDisposition.Size = stream.Length;
attach.ContentType.MediaType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 

另外,我发现我的创建后没有立即发送,其原因是“standalone = yes”没有被添加到所有页面的xml声明中,所以在我的AddParts函数中,之后添加部分,我将它们传递给这个函数:

private static void AddXMLStandalone(OpenXmlPart part)
        {
            System.IO.StreamWriter writer = new System.IO.StreamWriter(part.GetStream());

            XmlDocument doc = new XmlDocument();
            doc.Load(part.GetStream());

            doc.InnerXml = doc.InnerXml.Substring(doc.InnerXml.IndexOf("?>") + 2);
            doc.InnerXml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + doc.InnerXml;

            part.GetStream().SetLength(doc.InnerXml.Length);
            doc.Save(writer);
            writer.Flush();
            writer.Close();            
        }
祝你好运!

答案 1 :(得分:2)

这样做:

System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(new MemoryStream(stream.ToArray()), "MobileBill.xlsx", "application/vnd.ms-excel");

显然内存流没有刷新或者什么

答案 2 :(得分:1)

对于“内容不可读”问题,请确保保存()工作簿和工作表,并将您的SpreadsheetDocument包含在using语句中,以确保刷新,关闭所有包和压缩流等。

System.IO.MemoryStream stream = new System.IO.MemoryStream();
using (SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook)))
{
    AddParts(package); 
    //Save if AddParts hasn't done it
}
System.Net.Mail.Attachment file =  ...

答案 3 :(得分:0)

考虑加载:可能是,Attachment类希望从提供的流中的当前位置读取?如果是这种情况,在将其提供给Attachment构造函数之前,您可能必须“寻找”回流的开头:

AddParts(package); //created using document reflector
stream.Seek(0, SeekOrigin.Begin);
System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(stream, "MobileBill.xlsx", "application/vnd.ms-excel");