我正在使用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传递给视图......还有其他想法吗?
谢谢!
答案 0 :(得分:94)
我将我的解决方案打包在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表单身份验证([授权]属性)
保护要打印的操作,它也能正常工作答案 1 :(得分:10)
您可以在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”方法并将数据发送到内存流。
答案 2 :(得分:1)
这听起来像我在使用Views作为电子邮件模板时遇到的类似问题。我找到的获取视图字符串表示的最佳答案是:Render a view as a string
答案 3 :(得分:0)
我发现的最佳软件包是 RazorPDF ,可在NuGet.org上以iTextSharp为基础提供。适用于Azure网站: