iTextSharp-이메일 첨부 파일로 메모리 내 PDF 보내기


100

여기서 몇 가지 질문을했지만 여전히 문제가 있습니다. 내 코드에서 내가 뭘 잘못하고 있는지 말해 주시면 감사하겠습니다. 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 및 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);

3
이 질문을 해주셔서 감사합니다. 정확히 제가 찾던 것입니다.
Hardwareguy

1
의 라인에 감사드립니다 position=0. 나를 구했다!
Yisroel M. Olewski

2
정확히 내가 필요한 것이 완벽하게 작동합니다. 정말 감사합니다! 문서를 닫을 때 멈췄지만 스트림이 아닙니다. writer.CloseStream = false; 나를 위해 그것을 정리했습니다.
Baxter

2
@Semil은 받아 들여진 답변으로 오래된 질문에 현상금을 올릴 때 어떻게 든 답에서 놓친 부분을 표시해야합니다.
mkl jul.

writer.CloseStream = 거짓; 저를 구했습니다. iTextSharp를 사용하여 HTML을 PDF로 변환하는 방법에서 누락되었습니다. 이전에는 스트림이 닫혀서 메모리 스트림을 내 메일 함수에 전달하지 못했습니다. 감사.
Alec Menconi 2015 년

답변:


81

시도해 보셨습니까?

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

내 기억이 제대로 작동한다면 이전 프로젝트에서 비슷한 문제가 해결되었습니다.

http://forums.asp.net/t/1093198.aspx 참조


1
set_CloseStream 메소드는 Java 버전에서만 사용할 수 있습니다. 이다 iTextSharp (.NET)
이치

죄송합니다. 다시 한 번 iTextSharp (.NET)를 사용하지 않았지만 제가 사용한 버전에는 확실히 set_CloseStream이있었습니다.
brianng

1
writer.CloseStream으로 변경되고 관련 링크가 포함되었습니다.
brianng

1
브리앙, 도와 주셔서 정말 감사합니다. 나는 당신과 Ichiban이 그것을 통해 내 손을 잡았다는 것을 알고 있습니다. 감사!
Gus Cavalcanti

작가를 살려두면 언제쯤 writer.Flush()될까요?
Blaise

18

나는 brianng이 게시 한 코드를 시도해 보았고 작동했습니다. 코드 상단을 다음과 같이 변경하십시오.

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

3
시간을내어 확인해 주셔서 감사합니다!
brianng

1
Hi Ichiban, 그것은 컴파일하고 실제로 첨부 파일과 함께 이메일을 보내지 만 첨부 된 pdf 문서는 0kb로 나옵니다. 이메일로 보낸 pdf를 실제로 열었습니까?
Gus Cavalcanti

2
@Gustavo, 파일이 Acrobat 뷰어에서 올바르게 열립니다. 약 900 바이트입니다. 다음 줄을 유지해야합니다. memoryStream.Position = 0; doc.Close () 바로 뒤에. 나는 그것을 언급하는 것을 잊었다. (위 업데이트 참조)
ichiban

1
예! 많은 분들 감사합니다. 마침내 작동했습니다. 이치 ​​반의 대답은 brianng의 대답을 기반으로했기 때문에 brianng의 대답을 올바른 것으로 표시하는 것이 공정하다고 생각합니다.
Gus Cavalcanti

3

당신은 할 수 플러시 문서 또는 메모리 스트림을 당신이 그것을 연결 한 후 닫습니다?


안녕하세요 제임스. 이 작업을 수행했지만 결과가 변경되지 않았습니다. 여전히 "Closed Stream에 액세스 할 수 없습니다"오류가 발생합니다. :( 다른 아이디어?
Gus Cavalcanti

3

아마도 doc.Close ()를 호출 할 것입니다. 기본 스트림을 삭제합니다. doc.Close ()를 제거하고 해당 줄 대신 memoryStream.Position = 0을 설정하십시오.

또는 임시 파일을 사용할 수 있습니다.

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

huseyint, 나는 당신이 제안한 것을했고 pdf 파일이 전송되었지만 길이는 15 바이트에 불과합니다. 열어 보면 손상되었습니다. 나는 당신의 제안에 거의 도달했다고 느낍니다. 다른 아이디어가 있습니까? 감사!
Gus Cavalcanti

그런 다음 memoryStream.Flush (); 위치를 설정하기 전에
huseyint 2009-07-28

같은 것. 파일이 거의 비어 있고 손상되었습니다. :(
Gus Cavalcanti

"임시 파일 만들기"를 사용해 보셨습니까?
huseyint

지금 작업 중이며 곧 알려 드리겠습니다. 감사!
Gus Cavalcanti

1

나는 똑같은 문제가 있었고이 게시물을 사용하여 그것을 해결했습니다.

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

글을 쓰는 대신 생각 해요

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

새 스트림 만들기

MemoryStream m = new MemoryStream(memoryStream);

그리고 전화

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

둘 다 작동하지만 새 스트림을 만드는 것이 더 낫다고 생각합니다.


새 스트림을 만드는 것이 더 좋은 이유는 무엇입니까?
Andy

그렇지 않습니다. 바이트를 한 곳에서 다른 곳으로 복사해야하므로 메모리와 CPU 시간이 낭비됩니다.
Serguei Fedorov

내가 왜 더 낫다고 말했는지 기억하지 마십시오. 나는 그것이 더 명확하다는 것을 의미했을 것이라고 생각합니다. 방금 본건 미안 해요. 오랜만에 :)
Zein Sleiman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.