Jak renderować ASP.NET widok MVC w formacie PDF

Pracuję z ExpertPDF narzędzie konwersji Html-to-PDF na to pytanie (chociaż jestem otwarty na inne biblioteki, jeśli jest wystarczająca dokumentacja).

Krótko mówiąc, mam widok, który jest sformatowany w określony sposób i chciałbym renderować go jako dokument PDF, który użytkownik może zapisać na dysku.

Do tej pory mam PrintService (który implementuje interfejs IPrintService) i Ta implementacja ma dwa przeciążenia dla printtopdf (), jeden, który pobiera tylko adres URL, a drugi pobiera łańcuch HTML i oba zwracają bajt []. Opracowałem tylko szczegóły drugiego przeciążenia, które wymaga ciągu HTML.

To co chciałbym zrobić z mojego kontrolera to coś w stylu:

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");  
}

Który teoretycznie renderowałby plik PDF na stronę. Chodzi o to, że szukam pomocy. Czy istnieje szybki sposób na uzyskanie reprezentacji String widoku? A może powinienem po prostu trzymać się przeciążenia URL i przekazać w adresie URL do widoku... Jakieś inne myśli?

Dzięki!
Author: nkirkes, 2009-08-25

4 answers

Możesz użyć odpowiedzi podczas OnResultExecuting i zastąpić właściwość Filter czymś, co przechowuje wynikowy kod HTML w MemoryStream. Następnie możesz wyczyścić odpowiedź podczas OnResultExecuted i zastąpić ją wynikami konwersji PDF. Nie jestem pewien, czy byłoby to lepsze niż pobranie HTML z adresu URL.

 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() );
      }
}

PDFStreamFilter musi zastąpić metodę (metody) "Write" i wysłać dane do strumienia pamięci zamiast tego.

 8
Author: tvanfosson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-18 18:22:06

Moje rozwiązanie spakowałem w pakiet Nuget: Rotativa http://nuget.org/packages/Rotativa . opiera się na wkhtmltopdf.

Użycie jest naprawdę proste.

Posiadanie akcji, którą chcesz podać jako Pdf, zamiast strony Html. Możesz zdefiniować akcję, która zwraca ActionResult typu ActionAsPdf (dostępna jest również RouteAsPdf). Więc kod jest po prostu:

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

Z name = "Giorgio" będącym parametrem trasy.

Działa nawet jeśli akcja drukowania jest protected by Web forms authentication (atrybut [Authorize])

 91
Author: Giorgio Bozio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-22 09:55:08

To brzmi jak podobny problem, który miałem, gdy chciałem użyć widoków jako szablonów wiadomości e-mail. Najlepsza odpowiedź, jaką znalazłem dla uzyskania reprezentacji string widoku była tutaj: Render Widok jako string

 1
Author: Jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:05

Najlepszy pakiet jaki znalazłem to RazorPDF , dostępny jako pakiet na NuGet.org, na podstawie iTextSharp . Działa na witrynach internetowych platformy Azure:

Https://nuget.org/packages/RazorPDF

 0
Author: Cigano Morrison Mendez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-14 21:27:36