MVC में ब्राउज़र में पीडीएफ कैसे लौटाएं?


120

मेरे पास iTextSharp के लिए यह डेमो कोड है

    Document document = new Document();
    try
    {
        PdfWriter.GetInstance(document, new FileStream("Chap0101.pdf", FileMode.Create));

        document.Open();

        document.Add(new Paragraph("Hello World"));

    }
    catch (DocumentException de)
    {
        Console.Error.WriteLine(de.Message);
    }
    catch (IOException ioe)
    {
        Console.Error.WriteLine(ioe.Message);
    }

    document.Close();

मुझे ब्राउज़र में पीडीएफ दस्तावेज़ वापस करने के लिए नियंत्रक कैसे मिलेगा?

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

इस कोड को चलाने से एक्रोबेट खुल जाता है लेकिन मुझे एक त्रुटि संदेश मिलता है "फ़ाइल क्षतिग्रस्त है और उसकी मरम्मत नहीं की जा सकती है"

  public FileStreamResult pdf()
    {
        MemoryStream m = new MemoryStream();
        Document document = new Document();
        PdfWriter.GetInstance(document, m);
        document.Open();
        document.Add(new Paragraph("Hello World"));
        document.Add(new Paragraph(DateTime.Now.ToString()));
        m.Position = 0;

        return File(m, "application/pdf");
    }

किसी भी विचार क्यों यह काम नहीं करता है?



@ mg1075 आपका लिंक मृत है
thecoolmacdude

जवाबों:


128

एक वापसी FileContentResult। आपके नियंत्रक क्रिया में अंतिम पंक्ति कुछ इस तरह होगी:

return File("Chap0101.pdf", "application/pdf");

यदि आप इस पीडीएफ को गतिशील रूप से उत्पन्न कर रहे हैं, तो MemoryStreamफ़ाइल को सहेजने के बजाय मेमोरी का उपयोग करना और दस्तावेज़ बनाना बेहतर हो सकता है । कोड कुछ इस तरह होगा:

Document document = new Document();

MemoryStream stream = new MemoryStream();

try
{
    PdfWriter pdfWriter = PdfWriter.GetInstance(document, stream);
    pdfWriter.CloseStream = false;

    document.Open();
    document.Add(new Paragraph("Hello World"));
}
catch (DocumentException de)
{
    Console.Error.WriteLine(de.Message);
}
catch (IOException ioe)
{
    Console.Error.WriteLine(ioe.Message);
}

document.Close();

stream.Flush(); //Always catches me out
stream.Position = 0; //Not sure if this is required

return File(stream, "application/pdf", "DownloadName.pdf");

@ पहले, आपको दस्तावेज़ को बंद करने और स्ट्रीम को फ्लश करने की आवश्यकता है।
जिऑफ

2
ज्योफ, मैं इसे हासिल करने की कोशिश कर रहा हूं, लेकिन ऐसी ही समस्याएं हैं। मुझे रन टाइम में एक त्रुटि मिलती है "एक बंद स्ट्रीम तक नहीं पहुंच सकता" लेकिन अगर मैं इसे बंद नहीं करता हूं तो कुछ भी नहीं लौटाया जाता है।
छोटकी

1
धन्यवाद @littlechris आप ठीक कह रहे हैं, मैंने pdfWriter.CloseStream = false पर झुकाव के लिए कोड संपादित किया है;
ज्योफ

1
हां @ जीऑफ़ स्ट्रीम। पोज़िशन = 0; आवश्यक है, यदि आप इसे नहीं लिखते हैं, तो इस समय पीडीएफ एक्रोबेट एक त्रुटि "फाइल डैमेज" फेंकता है
अल्बर्टो लियोन

3
स्पष्ट रूप से 'System.Web.Mvc.FileStreamResult' प्रकार को 'System.Web.Mvc.FileContentResult' में नहीं बदल सकते हैं
CountMurphy

64

मैंने इसे इस कोड के साथ काम किया।

using iTextSharp.text;
using iTextSharp.text.pdf;

public FileStreamResult pdf()
{
    MemoryStream workStream = new MemoryStream();
    Document document = new Document();
    PdfWriter.GetInstance(document, workStream).CloseStream = false;

    document.Open();
    document.Add(new Paragraph("Hello World"));
    document.Add(new Paragraph(DateTime.Now.ToString()));
    document.Close();

    byte[] byteInfo = workStream.ToArray();
    workStream.Write(byteInfo, 0, byteInfo.Length);
    workStream.Position = 0;

    return new FileStreamResult(workStream, "application/pdf");    
}

डॉक्यूमेंट, PdfWriter और Paragraph बिना मान्यता के हैं। क्या नाम स्थान जोड़ा जाना है?
माइकल

9
मैं थोड़ा चिंतित usingहूं कि किसी भी उदाहरण में एक भी बयान नहीं है जो मुझे मिल सकता है ... क्या यहां इसकी आवश्यकता नहीं है? मुझे लगता है कि आपके पास कम से कम 3 डिस्पोजेबल ऑब्जेक्ट हैं ...
कोबी

हां, बयानों का उपयोग करना अच्छा है। यदि यह अधिक से अधिक के साथ एक उत्पादन ऐप है, तो कहें ... इसका उपयोग करने वाला एक व्यक्ति, इससे समस्या हो सकती है ...
vbullinger

7
FileSteamResult आपके लिए स्ट्रीम बंद कर देगा। इस उत्तर को देखें stackoverflow.com/a/10429907/228770
एड स्पेंसर

महत्वपूर्ण बात सेट स्थिति = 0. हाहा है। धन्यवाद @TonyBorf
ThanhLD

23

आपको निर्दिष्ट करना होगा:

Response.AppendHeader("content-disposition", "inline; filename=file.pdf");
return new FileStreamResult(stream, "application/pdf")

फ़ाइल को डाउनलोड किए जाने के बजाय सीधे ब्राउज़र में खोला जाएगा


धन्यवाद! मैं हर जगह खोज रहा था कि यह कैसे करना है !!
स्कूटी

17

यदि आप FileResultअपने एक्शन मेथड से लौटते हैं , और File()कंट्रोलर पर एक्सटेंशन मेथड का उपयोग करते हैं, तो आप जो चाहते हैं वह बहुत आसान है। इस File()पद्धति पर ओवरराइड होते हैं जो फ़ाइल की द्विआधारी सामग्री, फ़ाइल का पथ या ए Stream

public FileResult DownloadFile()
{
    return File("path\\to\\pdf.pdf", "application/pdf");
}

11

मैं इसी तरह की समस्याओं में चला गया हूं और मैंने एक समाधान के लिए ठोकर खाई है। मैंने दो पदों का उपयोग किया, एक स्टैक से जो डाउनलोड करने के लिए वापस आने की विधि दिखाता है और दूसरा वह जो इटक्शार्प और एमवीसी के लिए एक कार्यशील समाधान दिखाता है।

public FileStreamResult About()
{
    // Set up the document and the MS to write it to and create the PDF writer instance
    MemoryStream ms = new MemoryStream();
    Document document = new Document(PageSize.A4.Rotate());
    PdfWriter writer = PdfWriter.GetInstance(document, ms);

    // Open the PDF document
    document.Open();

    // Set up fonts used in the document
    Font font_heading_1 = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 19, Font.BOLD);
    Font font_body = FontFactory.GetFont(FontFactory.TIMES_ROMAN, 9);

    // Create the heading paragraph with the headig font
    Paragraph paragraph;
    paragraph = new Paragraph("Hello world!", font_heading_1);

    // Add a horizontal line below the headig text and add it to the paragraph
    iTextSharp.text.pdf.draw.VerticalPositionMark seperator = new iTextSharp.text.pdf.draw.LineSeparator();
    seperator.Offset = -6f;
    paragraph.Add(seperator);

    // Add paragraph to document
    document.Add(paragraph);

    // Close the PDF document
    document.Close();

    // Hat tip to David for his code on stackoverflow for this bit
    // /programming/779430/asp-net-mvc-how-to-get-view-to-generate-pdf
    byte[] file = ms.ToArray();
    MemoryStream output = new MemoryStream();
    output.Write(file, 0, file.Length);
    output.Position = 0;

    HttpContext.Response.AddHeader("content-disposition","attachment; filename=form.pdf");


    // Return the output stream
    return File(output, "application/pdf"); //new FileStreamResult(output, "application/pdf");
}

बहुत बढ़िया उदाहरण! यह ठीक वही है जिसकी मुझे तलाश थी! - पीट -
DigiOz मल्टीमीडिया

2
Usings? बंद करे? निपटान? फ्लश? स्मृति लीक के बारे में कौन परवाह करता है?
vbullinger

3

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

http://haacked.com/archive/2008/05/10/writing-a-custom-file-download-action-result-for-asp.net-mvc.aspx


7
जैसा कि उस ब्लॉग पोस्ट के शीर्ष पर कहा गया है, FileResult, Asp.Net MVC के साथ बॉक्स से बाहर आता है, इसलिए अपना स्वयं का कोडिंग अब आवश्यक नहीं है।
NerdFury

3

मुझे पता है कि यह सवाल पुराना है, लेकिन मुझे लगा कि मैं इसे साझा करूंगा क्योंकि मुझे ऐसा कुछ नहीं मिला।

मैं रेजर का उपयोग करके अपने विचार / मॉडल सामान्य बनाना चाहता था और उन्हें Pdfs के रूप में प्रस्तुत किया

इस तरह मैंने iTextSharp का उपयोग करके दस्तावेज़ को लेआउट करने के तरीके के बजाय मानक HTML आउटपुट का उपयोग करके पीडीएफ प्रस्तुति पर नियंत्रण किया था।

परियोजना और स्रोत कोड नौगेट इंस्टॉलेशन निर्देशों के साथ यहां उपलब्ध है:

https://github.com/andyhutch77/MvcRazorToPdf

Install-Package MvcRazorToPdf

3

FileStreamResultनिश्चित रूप से काम करता है। लेकिन अगर आप Microsoft डॉक्स को देखते हैं , तो यह विरासत में मिला है ActionResult -> FileResult, जिसमें एक और व्युत्पन्न वर्ग है FileContentResult। यह "प्रतिक्रिया के लिए एक बाइनरी फ़ाइल की सामग्री भेजता है"। इसलिए यदि आपके पास पहले से ही है byte[], तो आपको FileContentResultइसके बजाय बस का उपयोग करना चाहिए ।

public ActionResult DisplayPDF()
{
    byte[] byteArray = GetPdfFromWhatever();

    return new FileContentResult(byteArray, "application/pdf");
}

2

आप आम तौर पर एक Response.Flush के बाद एक Response.Close करेंगे, लेकिन किसी कारण से iTextSharp लाइब्रेरी को यह पसंद नहीं आता है। डेटा इसे माध्यम से नहीं बनाता है और एडोब को लगता है कि पीडीएफ भ्रष्ट है। Response.Close फ़ंक्शन को छोड़ दें और देखें कि क्या आपके परिणाम बेहतर हैं:

Response.Clear();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-disposition", "attachment; filename=file.pdf"); // open in a new window
Response.OutputStream.Write(outStream.GetBuffer(), 0, outStream.GetBuffer().Length);
Response.Flush();

// For some reason, if we close the Response stream, the PDF doesn't make it through
//Response.Close();

2
HttpContext.Response.AddHeader("content-disposition","attachment; filename=form.pdf");

यदि फ़ाइलनाम गतिशील रूप से उत्पन्न हो रहा है, तो यहाँ फ़ाइल नाम कैसे परिभाषित करें, यह यहां गाइड के माध्यम से उत्पन्न हो रहा है।


1

यदि आप पॉप-अप या ब्राउज़र पर पीडीएफ प्रदर्शित करने के लिए DB से var-Binary data लौटाते हैं, तो इस कोड का अनुसरण करें: -

पृष्ठ देखें:

@using (Html.BeginForm("DisplayPDF", "Scan", FormMethod.Post))
    {
        <a href="javascript:;" onclick="document.forms[0].submit();">View PDF</a>
    }

स्कैन नियंत्रक:

public ActionResult DisplayPDF()
        {
            byte[] byteArray = GetPdfFromDB(4);
            MemoryStream pdfStream = new MemoryStream();
            pdfStream.Write(byteArray, 0, byteArray.Length);
            pdfStream.Position = 0;
            return new FileStreamResult(pdfStream, "application/pdf");
        }

        private byte[] GetPdfFromDB(int id)
        {
            #region
            byte[] bytes = { };
            string constr = System.Configuration.ConfigurationManager.ConnectionStrings["Connection"].ConnectionString;
            using (SqlConnection con = new SqlConnection(constr))
            {
                using (SqlCommand cmd = new SqlCommand())
                {
                    cmd.CommandText = "SELECT Scan_Pdf_File FROM PWF_InvoiceMain WHERE InvoiceID=@Id and Enabled = 1";
                    cmd.Parameters.AddWithValue("@Id", id);
                    cmd.Connection = con;
                    con.Open();
                    using (SqlDataReader sdr = cmd.ExecuteReader())
                    {
                        if (sdr.HasRows == true)
                        {
                            sdr.Read();
                            bytes = (byte[])sdr["Scan_Pdf_File"];
                        }
                    }
                    con.Close();
                }
            }

            return bytes;
            #endregion
        }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.