Comment retourner PDF au navigateur dans MVC?

j'ai ce code démo pour 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();

Comment faire pour que le contrôleur renvoie le document pdf dans le navigateur?

EDIT:

L'exécution de ce code ouvre Acrobat mais je reçois un message d'erreur "le fichier est endommagé et ne peut pas être réparé"

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

des idées pourquoi cela ne fonctionne pas?

105
demandé sur hutchonoid 2009-10-02 20:00:46

10 réponses

Retour FileContentResult . La dernière ligne dans votre action de contrôleur serait quelque chose comme:

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

si vous générez Ce PDF dynamiquement, il peut être préférable d'utiliser un MemoryStream , et de créer le document en mémoire au lieu de sauvegarder dans le fichier. Le code serait quelque chose comme:

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");
114
répondu Geoff 2016-08-29 14:24:06

Je l'ai fait travailler avec ce code.

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");    
}
53
répondu Tony Borf 2011-09-12 17:59:25

vous devez préciser:

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

pour le fichier à être ouvert directement dans le navigateur au lieu d'être téléchargé

17
répondu Machinegon 2014-04-03 12:27:50

si vous retournez un FileResult de votre méthode d'action, et utilisez la méthode d'extension File() sur le contrôleur, faire ce que vous voulez est assez facile. Il y a des dérogations sur la méthode File() qui prendront le contenu binaire du fichier, le chemin vers le fichier, ou un Stream .

public FileResult DownloadFile()
{
    return File("path\to\pdf.pdf", "application/pdf");
}
15
répondu NerdFury 2009-10-02 16:20:08

j'ai rencontré des problèmes similaires et je suis tombé sur une solution. J'ai utilisé deux messages, un de stack qui montre la méthode de retour pour le téléchargement et un autre un qui montre une solution de travail pour ItextSharp et MVC.

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
    // /q/asp-net-mvc-how-to-get-view-to-generate-pdf-6492/"content-disposition","attachment; filename=form.pdf");


    // Return the output stream
    return File(output, "application/pdf"); //new FileStreamResult(output, "application/pdf");
}
11
répondu littlechris 2017-05-23 10:31:17

, Vous pouvez créer une classe personnalisée pour modifier le type de contenu et ajouter le fichier à la réponse.

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

3
répondu Chris Kooken 2009-10-02 16:05:10

je sais que cette question Est ancienne mais j'ai pensé que je partagerais cela car je ne pouvais rien trouver de semblable.

j'ai voulu créer mes vues/modèles comme la normale en utilisant le rasoir et les avoir rendus comme Pdfs .

de cette façon, j'ai eu le contrôle sur la présentation pdf en utilisant la sortie html standard plutôt que de comprendre comment mettre en page le document en utilisant iTextSharp.

le projet et le code source est disponible ici avec les instructions d'installation nuget:

https://github.com/andyhutch77/MvcRazorToPdf

Install-Package MvcRazorToPdf
3
répondu hutchonoid 2013-11-30 15:54:02

vous devez normalement répondre.Rincer suivie d'une Réponse.Proche, mais pour une raison quelconque la bibliothèque iTextSharp ne semble pas aimer cela. Les données ne passent pas et Adobe pense que le PDF est corrompu. Laisse-le en dehors de la Réponse.Fermez la fonction et voyez si vos résultats sont meilleurs:

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
répondu JML 2009-11-04 16:41:47

si vous retournez var - données binaires de DB pour afficher PDF sur popup ou navigateur signifie suivre ce code: -

"151970920 Afficher la page:

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

contrôleur de balayage:

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
        }
1
répondu ethiraj 2017-10-10 10:20:02
HttpContext.Response.AddHeader("content-disposition","attachment; filename=form.pdf");

si le nom du fichier est généré dynamiquement alors comment définir le nom du fichier ici, il est généré par guid ici.

1
répondu S.J.Lee 2018-07-04 06:44:25