116 votes

Comment renvoyer un PDF au navigateur dans MVC?

J'ai ce code de démonstration 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 au navigateur?

MODIFIER:

L'exécution de ce code ouvre Acrobat mais 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?

124voto

Geoff Points 2586

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

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

Si vous générez ce fichier PDF de manière dynamique, il peut être préférable d’utiliser un MemoryStream et de créer le document en mémoire au lieu de l’enregistrer dans un 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");
 

60voto

Tony Borf Points 1950

Je l'ai obtenu 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");    
}
 

20voto

Machinegon Points 522

Vous devez spécifier:

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

Pour que le fichier soit ouvert directement dans le navigateur au lieu d'être téléchargé

16voto

NerdFury Points 9935

Si vous renvoyez un FileResult de votre méthode d'action et utilisez la méthode d'extension File() sur le contrôleur, il est assez facile de faire ce que vous voulez. Il existe des substitutions sur la méthode File() qui prendront le contenu binaire du fichier, le chemin d'accès au fichier ou un Stream .

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

11voto

littlechris Points 1383

J'ai rencontré des problèmes similaires et je suis tombé sur une solution. J'ai utilisé deux publications, une de pile qui montre la méthode de retour pour le téléchargement et une autre qui montre une solution efficace 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
    // http://stackoverflow.com/questions/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");
}
 

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: