99 votes

iTextSharp - Envoi de pdf en mémoire dans une pièce jointe

J'ai demandé à un couple de questions ici, mais je suis toujours avoir des problèmes. J'apprécierais si vous pouviez me dire ce que je fais de mal dans mon code. J'exécute le code ci-dessus à partir d'un ASP.Net page et la faire "Impossible d'Accéder à un Fermé de Flux".

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

Merci!!!

EDIT:

Juste pour aider quelqu'un cherche la réponse à cette question, le code pour envoyer un fichier pdf en fichier joint à un e-mail sans avoir à se déplacer physiquement créer le fichier ci-dessous (merci à Ichiban et Brianng):

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

80voto

brianng Points 4478

As-tu essayé:

 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"));
 

Si ma mémoire est bonne, cela résout un problème similaire dans un projet précédent.

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

18voto

ichiban Points 4568

J'ai essayé le code posté par brianng et cela a fonctionné. Il suffit de changer le haut du code en ceci:

 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*/
 

3voto

huseyint Points 8196

Probablement appeler doc.Close () Supprime le flux sous-jacent. Essayez de supprimer doc.Close () et à la place de cette ligne, définissez memoryStream.Position = 0;

Sinon, vous pouvez utiliser un fichier temporaire:

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

3voto

James Conigliaro Points 3173

Pouvez-vous vider le document ou le flux de mémoire, puis le refermer après l'avoir attaché?

1voto

Zein Sleiman Points 85

J'ai eu le même problème et j'ai utilisé ce post pour le résoudre.Dans le code écrit par 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"));
 

Je pense au lieu d'écrire

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

Il suffit de créer un nouveau flux

 MemoryStream m = new MemoryStream(memoryStream);
 

et ensuite appeler

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

Les deux fonctionnent mais je pense qu'il est préférable de créer le nouveau flux

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X