iTextSharp - एक ईमेल अनुलग्नक में मेमोरी पीडीएफ़ भेजना


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

धन्यवाद!!!

संपादित करें:

इस प्रश्न के उत्तर की तलाश करने वाले किसी व्यक्ति की मदद करने के लिए, एक ईमेल से जुड़ी एक पीडीएफ फाइल भेजने के लिए कोड भौतिक रूप से फ़ाइल बनाने के बिना नीचे है (इचिबन और ब्रायन के लिए धन्यवाद):

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
यह सवाल पूछने के लिए धन्यवाद, यह वही है जो मैं देख रहा था।
हार्डवेयरगुए

1
की लाइन के लिए धन्यवाद position=0। मुझे बचाया!
यिसरेल एम। ओलेवस्की

2
वास्तव में मुझे जो काम चाहिए वो पूरी तरह से धन्यवाद! मैं दस्तावेज़ को बंद करने पर अड़ा हुआ था, लेकिन धारा नहीं: लेखक। CloseStream = false; यह मेरे लिए मंजूरी दे दी।
बैक्सटर

2
@ किसी पुराने प्रश्न पर एक स्वीकृत जवाब के साथ इनाम देते समय, आपको वास्तव में किसी तरह का संकेत देना चाहिए कि आप उत्तर में क्या याद करते हैं।
mkl

author.CloseStream = false; मुझे भी बचाया, गायब था कि HTML को पीडीएफ में बदलने के लिए iTextSharp का उपयोग करने वाली एक विधि में। इससे पहले, स्ट्रीम बंद होने के कारण मेरे मेल फ़ंक्शन में मेमोरीस्ट्रीम पास करना विफल रहा। धन्यवाद।
एलेक मेन्कोनी

जवाबों:


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 विधि केवल जावा संस्करण में उपलब्ध है। यह iTextSharp (.NET)
ichiban

क्षमा करें, फिर से मैंने थोड़ी देर में iTextSharp (.NET) का उपयोग नहीं किया है, हालांकि मैंने जिस संस्करण का उपयोग किया था वह निश्चित रूप से set_CloseStream था।
जुआन

1
लेखक के लिए बदल दिया गया है। CloseStream, और संबंधित लिंक शामिल हैं।
bringng

1
ब्रायन, मैं वास्तव में आपकी मदद की सराहना करता हूं। मैं आपको और इकिबन तरह का एहसास कराता हूं। धन्यवाद!
गस कैवलन्ती

यदि हम लेखक को जीवित रखते हैं, तो हम कब मान लेते हैं writer.Flush()?
ब्लाइस

18

मैंने ब्रायन द्वारा पोस्ट किए गए कोड की कोशिश की और यह काम कर गया। बस इसके ऊपर कोड बदलें:

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
सत्यापन के लिए समय निकालने के लिए धन्यवाद!
जुआन

1
हाय इचिबन, यह संकलित करता है और यह वास्तव में अनुलग्नक के साथ ईमेल भेजता है, लेकिन संलग्न पीडीएफ दस्तावेज़ 0kb के साथ आता है। क्या आपने वास्तव में भेजे गए ईमेल को पीडीएफ खोला है?
गस कैवलन्ती

2
@Gustavo, फ़ाइल एक्रोबैट दर्शक में सही ढंग से खुलती है। यह लगभग 900 बाइट्स है। सुनिश्चित करें कि आप लाइन रखते हैं: memoryStream.Position = 0; doc.Close () के ठीक बाद। मैं उसका उल्लेख करना भूल गया। (ऊपर अपडेट देखें)
ichiban

1
हाँ! आप लोगों को धन्यवाद। यह आखिरकार काम कर गया। चूँकि इकिबन का उत्तर ब्रायनग के आधार पर था, इसलिए मुझे लगता है कि ब्रायन के उत्तर को सही के रूप में चिह्नित करना उचित है।
गूस कैवलन्ती

3

क्या आप दस्तावेज़ या मेमोरी स्ट्रीम को फ्लश कर सकते हैं और इसे संलग्न करने के बाद इसे बंद कर सकते हैं?


नमस्ते जेम्स। मैंने ऐसा किया और परिणाम नहीं बदला - मुझे अभी भी "बंद पहुंच स्ट्रीम नहीं कर सकता" त्रुटि मिलती है। :( अन्य विचार?
गस कैवलन्ती

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

पति, मैंने वही किया जो आपने सुझाया था और पीडीएफ फाइल भेजी है, लेकिन यह केवल 15 बाइट्स लंबी है। जब मैं इसे खोलने की कोशिश करता हूं, तो यह दूषित होता है। मुझे लगता है कि मैं आपके सुझाव के साथ लगभग वहाँ हूँ। कोई अन्य विचार? धन्यवाद!
गूस कैवलन्ती 19

फिर मेमोरीस्ट्रीम ट्राय करें।फ्लश (); स्थिति निर्धारित करने से पहले
पति

वही चीज। फ़ाइल लगभग खाली और दूषित भेजी जाती है। :(
गस कैवलन्ती जूल

क्या आपने "एक अस्थायी फ़ाइल बनाना" दिया था?
पति

मैं अभी इस पर काम कर रहा हूं और शीघ्र ही आपको बता दूंगा। धन्यवाद!
गूस कैवलन्ती

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

दोनों काम करते हैं लेकिन मुझे लगता है कि नई धारा बनाना बेहतर है


नई स्ट्रीम बनाना बेहतर क्यों है?
एंडी

यह। यह मेमोरी और सीपीयू समय की बर्बादी है क्योंकि बाइट्स को एक से दूसरे में कॉपी करना पड़ता है।
सेर्गेई फेडोरोव

याद नहीं कि मैंने क्यों कहा कि यह बेहतर है। मुझे लगता है कि मेरा मतलब है कि यह स्पष्ट है। क्षमा करें बस यह देखा। बहुत समय बाद :)
ज़िन स्लीमैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.