代码之家  ›  专栏  ›  技术社区  ›  nkirkes

如何以PDF格式呈现ASP.NET MVC视图

  •  22
  • nkirkes  · 技术社区  · 15 年前

    我正在使用expertpdf的html-to-pdf转换工具来解决这个问题(尽管如果有足够的文档,我会向其他库开放)。

    简而言之,我有一个视图是以特定的方式格式化的,我想把它呈现为一个用户可以保存到磁盘上的PDF文档。

    到目前为止,我拥有的是一个printservice(它实现了一个i printservice接口),这个实现有两个printtopdf()的重载,一个只接受一个URL,另一个接受一个HTML字符串,两个都返回一个byte[]。我只计算了需要HTML字符串的第二个重载的细节。

    我想从控制器执行以下操作:

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

    从理论上讲,这会使页面呈现PDF格式。这是我正在寻找帮助的“一些关于rendersMyViewAsString的东西”。是否有快速获取视图的字符串表示形式的方法?或者我应该坚持使用URL重载并将URL传递给视图…还有其他想法吗?

    谢谢!

    4 回复  |  直到 7 年前
        1
  •  10
  •   J Wynia    12 年前

    在onResultExecuting期间,您可能能够点击响应,并用将结果HTML存储在memoryStream中的内容替换filter属性。然后,可以在OnResultExecuted期间清除响应,并将其替换为PDF转换的结果。不过,我不确定这是否比从URL获取HTML更好。

     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需要重写“write”方法并将数据发送到内存流。

        2
  •  94
  •   Giorgio Bozio    12 年前

    我把我的解决方案打包成一个Nuget包:Rotativa http://nuget.org/packages/Rotativa . 它基于wkhtmltopdf。

    使用非常简单。

    有一个动作,你想作为PDF,而不是HTML页面。您可以定义一个返回actionapspdf类型的actionresult的操作(routeaspdf也可用)。 所以代码只是:

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

    其中name=“giorgio”是一个路由参数。

    即使要打印的操作受Web窗体身份验证保护([authorize]属性),它也可以工作。

        3
  •  1
  •   Community datashaman    7 年前

    这听起来像是一个类似的问题,我想使用视图作为电子邮件模板。我找到的获取视图的字符串表示形式的最佳答案是: Render a view as a string

        4
  •  0
  •   Leonel Sanches da Silva    11 年前

    我找到的最好的包裹是 剃刀PDF ,作为一个包在nuget.org上提供,基于 iTextSharp .在Azure网站上工作:

    https://nuget.org/packages/RazorPDF