Отправка вложения электронной почты в памяти с использованием OpenXML - PullRequest
5 голосов
/ 25 июня 2009

У меня есть файл Excel, созданный с использованием OpenXML 2, и я хочу отправить его как вложение электронной почты. например,

    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 ]

5 голосов
/ 05 апреля 2010

Хорошо, у меня все получилось, хотя с некоторыми усилиями. Чтобы создать поток:

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();            
        }

Удачи!

2 голосов
/ 18 ноября 2011

сделать это:

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

Очевидно, что поток памяти не очищается или что-то в этом роде

1 голос
/ 03 июля 2009

При возникновении проблемы с «нечитаемым контентом» обязательно сохраните () свои рабочие книги и рабочие таблицы и включите свой 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 =  ...
0 голосов
/ 25 июня 2009

Думая нагрузка: может ли класс 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");
...