c# - mostrar - ¿Cómo devolver PDF al navegador en MVC?
mostrar pdf en mvc (9)
si devuelve datos binarios de DB para mostrar PDF en ventana emergente o navegador, siga este código: -
Ver pagina:
@using (Html.BeginForm("DisplayPDF", "Scan", FormMethod.Post))
{
<a href="javascript:;" onclick="document.forms[0].submit();">View PDF</a>
}
Controlador de escaneo:
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
}
Tengo este código de demostración para 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();
¿Cómo hago para que el controlador devuelva el documento pdf al navegador?
EDITAR:
Al ejecutar este código, se abre Acrobat pero aparece un mensaje de error "El archivo está dañado y no se pudo reparar".
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");
}
¿Alguna idea de por qué esto no funciona?
Debes especificar:
Response.AppendHeader("content-disposition", "inline; filename=file.pdf");
return new FileStreamResult(stream, "application/pdf")
Para que el archivo se abra directamente en el navegador en lugar de descargarse
Devuelve un FileContentResult
. La última línea en su acción de controlador sería algo así como:
return File("Chap0101.pdf", "application/pdf");
Si está generando este PDF dinámicamente, puede ser mejor utilizar un MemoryStream
y crear el documento en la memoria en lugar de guardarlo en un archivo. El código sería algo así como:
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");
Lo tengo trabajando con este código.
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");
}
Me encontré con problemas similares y me encontré con una solución. Utilicé dos publicaciones, una de la stack que muestra el método para volver a descargar y otra que muestra una solución de trabajo para ItextSharp y 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 for this bit
// https://.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");
}
Normalmente haría un Response.Flush seguido de un Response.Close, pero por alguna razón a la biblioteca iTextSharp no parece gustarle esto. Los datos no pasan y Adobe piensa que el PDF está dañado. Deje fuera la función Response.Close y vea si sus resultados son mejores:
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();
Puede crear una clase personalizada para modificar el tipo de contenido y agregar el archivo a la respuesta.
Sé que esta pregunta es antigua, pero pensé que podría compartir esto ya que no pude encontrar nada similar.
Quería crear mis vistas / modelos de forma normal usando Razor y hacer que se renderizaran como Pdfs .
De esta forma, tuve control sobre la presentación de PDF utilizando la salida html estándar en lugar de averiguar cómo diseñar el documento usando iTextSharp.
El proyecto y el código fuente están disponibles aquí con las instrucciones de instalación de nuget:
https://github.com/andyhutch77/MvcRazorToPdf
Install-Package MvcRazorToPdf
Si devuelve un FileResult
de su método de acción y utiliza el método de extensión File()
en el controlador, hacer lo que quiera es bastante fácil. Hay modificaciones en el método File()
que tomarán los contenidos binarios del archivo, la ruta al archivo o un Stream
.
public FileResult DownloadFile()
{
return File("path//to//pdf.pdf", "application/pdf");
}