如何以 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:如何让 Html.ActionLink 正确呈现整数值?
如何避免 ASP.NET MVC 中的 HttpRequestValidationException 呈现导致异常的相同视图