Comment renvoyer 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 puis-je demander au contrôleur de renvoyer le document pdf au navigateur?

MODIFIER:

L’exécution de ce code n’ouvre pas Acrobat mais je reçois un message d’erreur “Le fichier est endommagé et n’a pas pu ê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.ToSsortingng())); m.Position = 0; return File(m, "application/pdf"); } 

Des idées pourquoi cela ne fonctionne pas?

Retourne un 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 PDF de manière dynamic, 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"); 

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.ToSsortingng())); document.Close(); byte[] byteInfo = workStream.ToArray(); workStream.Write(byteInfo, 0, byteInfo.Length); workStream.Position = 0; return new FileStreamResult(workStream, "application/pdf"); } 

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é

Si vous retournez un FileResult partir 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 simple. La méthode File() est remplacée par le contenu binary du fichier, le chemin du fichier ou un Stream .

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

J’ai rencontré des problèmes similaires et je suis tombé sur une solution. J’ai utilisé deux articles, un de stack qui montre la méthode à retourner pour le téléchargement et un autre 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 // https://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"); } 

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

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

Je sais que cette question est ancienne mais je pensais que je partagerais ceci car je ne pouvais rien trouver de similaire.

Je voulais créer mes vues / modèles normalement en utilisant Razor et les rendre sous forme de fichiers PDF .

De cette façon, j’ai eu le contrôle de la présentation pdf en utilisant la sortie HTML standard plutôt que de trouver comment mettre en page le document en utilisant iTextSharp.

Le projet et le code source sont disponibles ici avec les instructions d’installation de nuget:

https://github.com/andyhutch77/MvcRazorToPdf

 Install-Package MvcRazorToPdf 

Vous feriez normalement un Response.Flush suivi d’un Response.Close, 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. Laissez la fonction Response.Close 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(); 

Si vous retournez des données var-binary à partir de DB pour afficher un PDF dans une fenêtre contextuelle ou un navigateur, suivez ce code: –

Voir page:

 @using (Html.BeginForm("DisplayPDF", "Scan", FormMethod.Post)) { View PDF } 

Contrôleur de numérisation:

 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 = { }; ssortingng constr = System.Configuration.ConfigurationManager.ConnectionSsortingngs["Connection"].ConnectionSsortingng; 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 } 
 HttpContext.Response.AddHeader("content-disposition","attachment; filename=form.pdf"); 

Si le nom de fichier génère dynamicment alors comment définir le nom de fichier ici, il génère via guid ici.