I've got an Excel file that's built using OpenXML 2 and I want to send it as an email attachment. e.g.
我有一个使用OpenXML 2构建的Excel文件,我想将其作为电子邮件附件发送。例如
System.IO.MemoryStream stream = new System.IO.MemoryStream();
SpreadsheetDocument package = SpreadsheetDocument.Create(stream, SpreadsheetDocumentType.Workbook))
AddParts(package); //created using document reflector
Saving the spreadsheet to a temp file using
使用将电子表格保存到临时文件
stream.WriteTo(new System.IO.FileStream(@"c:\test.xlsx", System.IO.FileMode.Create));
works fine. But trying to send the stream directly as an email attachment fails - just get an empty file attached to the email when I do
工作良好。但是尝试直接将流作为电子邮件附件发送失败 - 当我这样做时,只需在电子邮件中附加一个空文件
System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(stream, "MobileBill.xlsx", "application/vnd.ms-excel");
Anbody know how to do this?
有人知道怎么做吗?
4 个解决方案
#1
Ok, I got this working, though through some effort. To create the stream:
好吧,我通过一些努力得到了这个。要创建流:
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";
Also, I found that mine were not being sent right after I created them, and the reason for that is "standalone=yes" was not being added to the xml declaration of all the pages, so in my AddParts function, after adding the parts, I passed them into this function:
另外,我发现在创建它之后没有立即发送我的,并且其原因是“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();
}
Good luck!
#2
do this:
System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(new MemoryStream(stream.ToArray()), "MobileBill.xlsx", "application/vnd.ms-excel");
Apparently the memory stream doesn't get flushed or something
显然,内存流不会被刷新或其他东西
#3
For your "content unreadable" problem, make sure to Save() your Workbooks and Worksheets and enclose your SpreadsheetDocument in a using statement to ensure all packages and zipped streams are flushed, closed and so on.
对于“内容不可读”问题,请确保保存()工作簿和工作表,并将您的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 = ...
#4
Thinking out load: could it be, that the Attachment class expects to read from the current possition in the provided stream? If this is the case, you would probably have to "seek" back to the beginning of the stream, before feeding it to the Attachment constructor:
考虑加载:可能是,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");
#1
Ok, I got this working, though through some effort. To create the stream:
好吧,我通过一些努力得到了这个。要创建流:
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";
Also, I found that mine were not being sent right after I created them, and the reason for that is "standalone=yes" was not being added to the xml declaration of all the pages, so in my AddParts function, after adding the parts, I passed them into this function:
另外,我发现在创建它之后没有立即发送我的,并且其原因是“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();
}
Good luck!
#2
do this:
System.Net.Mail.Attachment file = new System.Net.Mail.Attachment(new MemoryStream(stream.ToArray()), "MobileBill.xlsx", "application/vnd.ms-excel");
Apparently the memory stream doesn't get flushed or something
显然,内存流不会被刷新或其他东西
#3
For your "content unreadable" problem, make sure to Save() your Workbooks and Worksheets and enclose your SpreadsheetDocument in a using statement to ensure all packages and zipped streams are flushed, closed and so on.
对于“内容不可读”问题,请确保保存()工作簿和工作表,并将您的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 = ...
#4
Thinking out load: could it be, that the Attachment class expects to read from the current possition in the provided stream? If this is the case, you would probably have to "seek" back to the beginning of the stream, before feeding it to the Attachment constructor:
考虑加载:可能是,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");