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

我正在使用ExpertPDF的Html-to-PDF转换实用程序来解决这个问题(尽管如果有足够的文档,我会对其他库开放)。

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

到目前为止我所拥有的是一个PrintService(它实现了一个IPrintService接口),这个实现有两个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呈现给页面。 这是我正在寻求帮助的“SomethingThatRendersMyViewAsAString”。 有没有快速的方法来获取视图的字符串表示? 或许我应该坚持使用URL重载并将URL传递给视图……还有其他想法吗?

谢谢!

您可以在OnResultExecuting期间使用Response并将Filter属性替换为在MemoryStream中存储结果HTML的内容。 然后,您可以在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”方法并将数据发送到内存流。

我将我的解决方案打包在Nuget包中:Rotativa http://nuget.org/packages/Rotativa 。 它基于wkhtmltopdf。

用法非常简单。

有一个动作,你想作为Pdf,而不是Html页面。 您可以定义一个返回ActionAsPdf类型的ActionResult的操作(RouteAsPdf也可用)。 所以代码只是:

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

名称=“Giorgio”是路线参数。

即使要通过Web窗体身份validation([Authorize]属性)保护要打印的操作,它也能工作

这听起来像我在使用Views作为电子邮件模板时遇到的类似问题。 我找到了获取View的字符串表示的最佳答案: 将视图渲染为字符串

我发现的最好的软件包是RazorPDF ,可以在NuGet.org上以iTextSharp的forms提供 。 适用于Azure网站:

https://nuget.org/packages/RazorPDF