Comment rendre ASP.NET MVC View en format PDF

je travaille avec L'utilitaire de conversion Html-to-PDF D'ExpertPDF pour cette question (bien que je sois ouvert à d'autres bibliothèques s'il y a suffisamment de documentation).

en bref, j'ai une vue qui est formatée d'une manière spécifique et je voudrais la rendre comme un document PDF que l'utilisateur peut sauvegarder sur disque.

ce que j'ai jusqu'à présent est un PrintService (qui implémente une interface IPrintService) et cette implémentation a deux surcharges pour PrintToPDF(), une qui prend juste une URL et une autre qui prend une chaîne HTML, et les deux renvoient un octet []. J'ai seulement travaillé sur les détails de la deuxième surcharge qui nécessite la chaîne HTML.

Ce que je voudrais faire de mon contrôleur est quelque chose comme:

public FileStreamResult Print(int id)
{
    var model = _CustomRepository.Get(id);
    string renderedView = SomethingThatRendersMyViewAsAString(model);
    Stream byteStream = _PrintService.PrintToPdf(renderedView);
    HttpContext.Response.AddHeader("content-disposition", 
        "attachment; filename=report.pdf");
    return new FileStreamResult(byteStream, "application/pdf");  
}

qui, en théorie, rendrait un PDF à la page. C'est le" quelque chose qui rend la vie difficile " que je cherche de l'aide. Est-il un moyen rapide pour obtenir la chaîne la représentation d'une Vue? Ou peut-être que je devrais simplement rester avec la surcharge D'URL et passer dans une URL à la vue... Toutes les autres pensées?

Merci!

21
demandé sur nkirkes 2009-08-25 00:34:50

4 réponses

vous pourriez être en mesure de puiser dans la réponse pendant OnResultExecuting et remplacer la propriété Filter par quelque chose qui stocke le HTML résultant dans un MemoryStream. Ensuite, vous pouvez effacer la réponse pendant OnResultExecuted et la remplacer par les résultats de votre conversion PDF. Je ne suis pas sûr que ce serait mieux que de simplement obtenir le HTML à partir de L'URL, bien que.

 public FileStreamResult Print(int id)
 {
     var model = _CustomRepository.Get(id);
     this.ConvertToPDF = true;
     return View( "HtmlView" );
 }

 public override OnResultExecuting( ResultExecutingContext context )
 {
      if (this.ConvertToPDF)
      {
          this.PDFStream = new MemoryStream();
          context.HttpContext.Response.Filter = new PDFStreamFilter( this.PDFStream );
      }
 }

 public override OnResultExecuted( ResultExecutedContext context )
 {
      if (this.ConvertToPDF)
      {
          context.HttpContext.Response.Clear();
          this.PDFStream.Seek( 0, SeekOrigin.Begin );
          Stream byteStream = _PrintService.PrintToPDF( this.PDFStream );
          StreamReader reader = new StreamReader( byteStream );
          context.HttpContext.Response.AddHeader( "content-disposition",
                 "attachment; filename=report.pdf" );
          context.HttpContext.Response.AddHeader( "content-type",
                 "application/pdf" );
          context.HttpContext.Response.Write( reader.ReadToEnd() );
      }
}

le PDFStreamFilter devrait outrepasser la(Les) méthode (s)" Write " et envoyer les données vers le flux de mémoire à la place.

8
répondu tvanfosson 2012-07-18 18:22:06

j'ai emballé ma solution dans un paquet Nuget: Rotativa http://nuget.org/packages/Rotativa . C'est basé sur wkhtmltopdf.

L'utilisation de

est très simple.

ayant une action que vous souhaitez servir en tant que Pdf, au lieu de page Html. Vous pouvez définir une action qui renvoie un résultat D'Action du type ActionAsPdf (RouteAsPdf est également disponible). Donc le code est juste:

public ActionResult PrintIndex()
{
    return new ActionAsPdf("Index", new { name = "Giorgio" }) { FileName = "Test.pdf" };
}

avec nom = "Giorgio" étant un paramètre de route.

cela fonctionne même si l'action d'imprimer est protégée par l'authentification des formulaires web (attribut[Authorize])

91
répondu Giorgio Bozio 2012-02-22 09:55:08

cela ressemble à un problème similaire que j'ai eu où je voulais utiliser des vues comme modèles de courrier électronique. La meilleure réponse que j'ai trouvé pour obtenir la représentation de chaîne de Vue est ici: Render vue comme une chaîne de caractères

1
répondu Jason 2017-05-23 12:18:05

le meilleur paquet que j'ai trouvé est le RazorPDF , disponible en paquet à NuGet.org, basé sur iTextSharp . Œuvres sur les Sites Web Azure:

https://nuget.org/packages/RazorPDF

0
répondu Cigano Morrison Mendez 2013-07-14 21:27:36