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

Posted

技术标签:

【中文标题】如何以 PDF 格式呈现 ASP.NET MVC 视图【英文标题】:How to render an ASP.NET MVC View in PDF format 【发布时间】:2010-11-22 09:57:33 【问题描述】:

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

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

到目前为止,我有一个 PrintService(它实现了一个 IPrintService 接口),这个实现有两个 PrintToPDF() 的重载,一个只接受一个 URL,另一个接受一个 HTML 字符串,两者都返回一个字节[]。我只计算了需要 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 传递给视图......还有其他想法吗?

谢谢!

【问题讨论】:

mannish - 你有没有在任何地方发布你的解决方案?这将非常有用。蒂亚 【参考方案1】:

我将我的解决方案打包在 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" ;

name = "Giorgio" 作为路由参数。

即使要打印的操作受到 Web 表单身份验证([Authorize] 属性)的保护,它也可以工作

【讨论】:

这是迄今为止我遇到的最简单的 asp.net mvc 解决方案,非常感谢... 这太棒了 - 谢谢!我会注意到我必须指定表单身份验证 cookie 名称(否则将呈现登录页面)并将渲染器更改为使用打印媒体样式(FormsAuthenticationCookieName = "MyCookie", CustomSwitches = "--print-media-type" )。很简单! Rotativa 似乎在 MVC4 上失败了。当我返回 ActionAsPdf 时,我看到屏幕上显示的是字符串而不是 PDF。 适用于 Azure Web 角色,但由于信任级别的限制,不适用于 Azure 网站。 @GuruprasadRao ,结果是 pdf 上的登录页面【参考方案2】:

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

【讨论】:

我找到了一个减少代码的解决方案,但您提供的答案是一个潜在的解决方案。拦截 Result 执行的好主意...我会尽快发布我的解决方案。【参考方案3】:

这听起来与我想将视图用作电子邮件模板的类似问题。我发现获取视图的字符串表示的最佳答案是:Render a view as a string

【讨论】:

我看到了那个帖子。根据对 brightmix 帖子的评论,我最终使用了类似的解决方案。我会尽快发布解决方案。【参考方案4】:

我发现的最好的包是 RazorPDF,它可以在 NuGet.org 上作为一个包提供,基于 iTextSharp。适用于 Azure 网站:

https://nuget.org/packages/RazorPDF

【讨论】:

以上是关于如何以 PDF 格式呈现 ASP.NET MVC 视图的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET MVC 将部分视图呈现为字符串以返回 JSON [重复]

来自数据库的 Pdf 文件以在 asp.net mvc 中查看

ASP.NET MVC:删除操作后,索引未呈现

Asp.Net MVC:如何让 Html.ActionLink 正确呈现整数值?

如何避免 ASP.NET MVC 中的 HttpRequestValidationException 呈现导致异常的相同视图

ASP.NET 和实体框架:PDF 报告不在本地 iis 服务器上呈现