Как визуализировать представление ASP.NET MVC в формате PDF
Я работаю с утилитой для конвертации HTML файлов в ExcelPDF для этого вопроса (хотя я открыт для других библиотек при наличии достаточной документации).
Короче говоря, у меня есть представление, которое форматируется определенным образом, и я хотел бы сделать его как документ 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-адрес в представление... Любые другие мысли?
Спасибо!
Ответы
Ответ 1
Возможно, вы сможете использовать Response во время OnResultExecuting и заменить свойство Filter тем, что хранит полученный HTML-код в MemoryStream. Затем вы можете очистить ответ во время OnResultExecuted и заменить его результатами вашего преобразования PDF. Я не уверен, что это будет лучше, чем просто получить HTML-код из URL.
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) "Write" и вместо этого отправить данные в поток памяти.
Ответ 2
Я упаковал свое решение в пакете Nuget: Rotativa http://nuget.org/packages/Rotativa. Он основан на wkhtmltopdf.
Использование действительно просто.
У вас есть действие, которое вы хотели бы использовать как Pdf, а не Html-страницу. Вы можете определить действие, которое возвращает ActionResult типа ActionAsPdf (также доступен RouteAsPdf).
Итак, код просто:
public ActionResult PrintIndex()
{
return new ActionAsPdf("Index", new { name = "Giorgio" }) { FileName = "Test.pdf" };
}
С именем = "Giorgio", являющимся параметром маршрута.
Он работает, даже если действие для печати защищено аутентификацией веб-форм (атрибут [Authorize])
Ответ 3
Это похоже на аналогичную проблему, с которой я хотел использовать Views в качестве шаблонов электронной почты. Лучший ответ, который я нашел для получения строкового представления представления, был здесь: Отобразить представление как строку
Ответ 4
Render MVC view и конвертировать его в PDF можно с помощью PdfProLib HTML to PDF Converter lib. В нем есть пример с именем ConverterMvc, демонстрирующий, как это сделать. В основном библиотека преобразует ваше MVC-представление в PDF и сохраняет документ PDF в объект FileResult
Ответ 5
Лучший пакет, который я нашел, - это RazorPDF, доступный как пакет на NuGet.org, на основе iTextSharp. Работает на веб-сайтах Azure:
https://nuget.org/packages/RazorPDF