ITextSharp-在电子邮件附件中发送内存 pdf

我已经问了几个问题,但还是有问题。如果您能告诉我代码中哪里出错了,我将不胜感激。我从 ASP.Net 页面运行上面的代码,得到“无法访问已关闭的流”。

var doc = new Document();


MemoryStream memoryStream = new MemoryStream();


PdfWriter.GetInstance(doc, memoryStream);
doc.Open();
doc.Add(new Paragraph("First Paragraph"));
doc.Add(new Paragraph("Second Paragraph"));


doc.Close(); //if I remove this line the email attachment is sent but with 0 bytes


MailMessage mm = new MailMessage("username@gmail.com", "username@gmail.com")
{
Subject = "subject",
IsBodyHtml = true,
Body = "body"
};


mm.Attachments.Add(new Attachment(memoryStream, "test.pdf"));
SmtpClient smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
Credentials = new NetworkCredential("username@gmail.com", "my_password")
};


smtp.Send(mm); //the "Cannot Access a Closed Stream" error is thrown here

谢谢! ! !

编辑:

只是为了帮助人们寻找这个问题的答案,发送附加到电子邮件的 pdf 文件而不必亲自创建文件的代码如下(感谢 Ichiban 和布赖恩) :

var doc = new Document();
MemoryStream memoryStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream);


doc.Open();
doc.Add(new Paragraph("First Paragraph"));
doc.Add(new Paragraph("Second Paragraph"));


writer.CloseStream = false;
doc.Close();
memoryStream.Position = 0;


MailMessage mm = new MailMessage("username@gmail.com", "username@gmail.com")
{
Subject = "subject",
IsBodyHtml = true,
Body = "body"
};


mm.Attachments.Add(new Attachment(memoryStream, "filename.pdf"));
SmtpClient smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
Credentials = new NetworkCredential("username@gmail.com", "password")


};


smtp.Send(mm);
52923 次浏览

Probably calling doc.Close() Disposes the underlying stream. Try removing doc.Close() and instead of that line set memoryStream.Position = 0;

Alternatively you can use a temp file:

var tempFilePath = Path.GetTempFileName();


try
{
var doc = new Document();


PdfWriter.GetInstance(doc, File.OpenWrite(tempFilePath));
doc.Open();
doc.Add(new Paragraph("First Paragraph"));
doc.Add(new Paragraph("Second Paragraph"));


doc.Close();


MailMessage mm = new MailMessage("username@gmail.com", "username@gmail.com")
{
Subject = "subject",
IsBodyHtml = true,
Body = "body"
};


mm.Attachments.Add(new Attachment(tempFilePath, "test.pdf"));
SmtpClient smtp = new SmtpClient
{
Host = "smtp.gmail.com",
Port = 587,
EnableSsl = true,
Credentials = new NetworkCredential("username@gmail.com", "my_password")
};


smtp.Send(mm);
}
finally
{
File.Delete(tempFilePath);
}

Can you flush the document or memory stream and then close it after you attach it?

Have you tried:

PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream);


// Build pdf code...


writer.CloseStream = false;
doc.Close();


// Build email


memoryStream.Position = 0;
mm.Attachments.Add(new Attachment(memoryStream, "test.pdf"));

If my memory serves me correctly, this solved a similar problem in a previous project.

See http://forums.asp.net/t/1093198.aspx

I tried the code posted by brianng and it worked. Just change the top of the code to this:

var doc = new Document();
MemoryStream memoryStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream); //capture the object
doc.Open();
doc.Add(new Paragraph("First Paragraph"));
doc.Add(new Paragraph("Second Paragraph"));
writer.CloseStream = false; //set the closestream property
doc.close(); //close the document without closing the underlying stream
memoryStream.Position = 0;


/* remainder of your code stays the same*/

I had the same problem and I used this post to solve it.In the code written by brianng

PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream);


// Build pdf code...


writer.CloseStream = false;
doc.Close();


// Build email


memoryStream.Position = 0;
mm.Attachments.Add(new Attachment(memoryStream, "test.pdf"));

I think instead of writing

writer.CloseStream = false and memoryStream.Position = 0;

Just create a new Stream

MemoryStream m = new MemoryStream(memoryStream);

and then call

mm.Attachments.Add(new Attachment(memoryStream, "test.pdf"));

Both work but I think it is better to create the new stream