[Tip/Trick] ASP.NET MVC & PDF

Uno de las preguntas que se suele encontrar en los foros MSDN  es como mostrar un fichero PDF desde ASP.NET y como últimamente he estado trabajando con MVC y me parece muy interesante voy a mostrar como se puede hacer esto desde el controlador.

Normalmente podemos optar por dos estratégicas a la hora de mostrar un documento PDF.

1. Mostrar un fichero

Si tenemos un fichero pdf que queremos mostrar crearemos un controlador que se encargue de mostrar este recurso.

 

Con MVC tenemos un método del controlador que nos facilita muchísimo el trabajo File que se encarga de enviar el contenido de un fichero binario a la respuesta y solo tenemos que indicar el tipo “contentType” para que se muestra correctamente.

public ActionResult GetPDF()
{
  string filename = @"~Contentjquery.cheatsheet.1.4.pdf";
  return File(filename, "application/pdf",
      Server.HtmlEncode(filename));
}

De esta manera podemos mostrar ficheros pdf, exel, word, etc. De una manera facilísima.

2. Generar un documento Pdf al vuelo

Para poder mostrar el documento pdf correctamente tendemos que utilizar alguna de las librerías gratuitas que existen en la red y en este ejemplo yo he optado por itextSharp.

Crearemos otra acción que generará un documento pdf dinámicamente, de esta manera podremos elegir crear el documento enteramente nosotros por código o utilizar una vista como plantilla para el documento.

Yo he creado una vista parcial “userControl” para generar el documento.

Describiré un poco el código de esta Acción:

public ActionResult PDF()
{
   ControllerContext context = this.ControllerContext;
   string partialViewName = "PDF";

   byte[] buf = null;
   MemoryStream pdfTemp = new MemoryStream();
   ViewEngineResult result = ViewEngines.Engines.FindPartialView
    (context, partialViewName);

   if (result.View != null)
   {
      string htmlTextView = GetViewToString(context, result);
      iTextSharp.text.Document doc = new iTextSharp.text.Document();
      iTextSharp.text.pdf.PdfWriter writer =
        iTextSharp.text.pdf.PdfWriter.GetInstance(doc, pdfTemp);
      writer.CloseStream = false;
      doc.Open();
      doc.Add(new iTextSharp.text.Paragraph("Documento PDF al Vuelo"));

      AddHTMLText(doc, htmlTextView);
      doc.Close();

      buf = new byte[pdfTemp.Position];
      pdfTemp.Position = 0;
      pdfTemp.Read(buf, 0, buf.Length);
   }
   return File(buf, "application/pdf", "tempPdf.pdf");
}

8: obtendremos la vista que queremos utilizar como plantilla para el documento pdf.

13: Obtendremos el contenido HTML de la vista como texto. Para eso utilizaremos el método GetViewToString.

16: Guardaremos el documento en memoria “memoryStream” para volcar el resultado posteriormente en la respuesta.

19: Podemos crear el documento por código.

21: Añadiremos el contenido de la vista al documento como texto HTML utilizando el método AddHTMLText().

26: Finalmente retornaremos el documento generado al vuelo como un fichero guardado en memoria.

private string GetViewToString(ControllerContext context,
      ViewEngineResult result)
{
   string viewResult = "";
   ViewDataDictionary viewData = new ViewDataDictionary();
   TempDataDictionary tempData = new TempDataDictionary();
   StringBuilder sb = new StringBuilder();
   using (StringWriter sw = new StringWriter(sb))
   {
      using (HtmlTextWriter output = new HtmlTextWriter(sw))
      {
        ViewContext viewContext = new ViewContext(context,
          result.View, viewData, tempData, output);
        result.View.Render(viewContext, output);
      }
      viewResult = sb.ToString();
   }
 return viewResult;
}

 

private void AddHTMLText(iTextSharp.text.Document doc, string html)
{
   List<iTextSharp.text.IElement> htmlarraylist =
       HTMLWorker.ParseToList(new StringReader(html), null);                

   foreach (var item in htmlarraylist)
   {
      doc.Add(item);
   }
}

 

Espero poder seguir haciendo más prácticas de este estilo con MVC, porque me esta gustando mucho ;-)

 

 

17 comentarios en “[Tip/Trick] ASP.NET MVC & PDF

  1. santa edith dijo:

    Hola esta interesante tu información… Me gustaría saber si tienes algun tutorial para guardar imagenes con Asp.Net Mvc2 y SqlServer 2008 es que por mas que he buscado no encuentro nada en Internet… De antemano gracias

    • Marc Rubiño dijo:

      Pues con esas caracteristicas no tengo nada, lo tomo como sugerencia para una nueva entrada.
      Despues del puente le dedicarçe algo de tiempo ;)

      Saludos

  2. Manuel Sepulveda dijo:

    Estimado muy buen post, de hecho soy nuevo en asp.net mvc y con tu ejemplo
    me aclare más mis dudas respecto a la estructura. Pero tengo una duda
    cuando llamas al controlador, de que viewer lo llamas y como??
    Saludos.
    Atte. Manuel Sepulveda

  3. jose antonio dijo:

    Hola amigo de new por aca mira me sale un pequeño errorsito quizas es por la libreria de iTextSharp y el error es en esta linea.

    List htmlarraylist =
    HTMLWorker.ParseToList(new StringReader(html), null);

    donde me dice que HTMLWorker no se encuentra dentro del contexto actual.

    y gracias de new

  4. jose antonio dijo:

    si hago referencia de echo la hize manuel en el controlador por que no me daba la opcion el IDE fijate que me paso algo curioso baje una de las librerias que tu proporcionas en tu link y me marco en varios controles lo mismo busque otra descargue y hize referencia y me quito las demas solo me quedo la de HTMLWorker quizas eleji la equivoca del link que pasastes.

  5. jose antonio dijo:

    gracias ya quedo Marc son dos buenos tuto de verdad en internet no hay informacion de esto con mvc3 sigue asi ahora me dedicare al de excel suert y exito

  6. jose antonio dijo:

    funciona muy bien tu ejemplo encerio corre a la perfeccion y disculpa pero soy algo nuevo en MVC3 una preguntita y si en este caso le quisiera pasar una consulta por el controlador iria algo asi verdad.

    doc.Add(aqui iria la consulta verdad»));
    de echo es toy utilizando LINQ

Deja un comentario