Asp.Net MVC, как получить представление для создания PDF

Я хотел бы вызвать действие на контроллере. Пусть контроллер получит данные от модели. Затем представление запускается и генерирует PDF. Единственный пример, который я нашел, находится в статье Лу http://whereslou.com/2009/04/12/returning-pdfs-from-an-aspnet-mvc-action. Его код очень элегантный. Представление использует ITextSharp для создания PDF. Единственный недостаток - его пример использует Spark View Engine. Есть ли способ сделать подобное с помощью стандартного движка Microsoft View?

7 ответов

Решение

Наш окончательный ответ на эту проблему заключался в использовании Rotativa.

Он оборачивает WKhtmltopdf.exe, как и некоторые другие решения, но это самый простой в использовании, который я нашел

Я пошел и проголосовал за все остальные ответы, которые также хорошо решают проблему, но это то, что мы использовали для решения проблемы, поставленной в вопросе выше. Это отличается от других ответов.

Вот учебник Rotativa.

после того, как вы установите его, это все, что вам нужно

public ActionResult PrintInvoice(int invoiceId)
{
  return new ActionAsPdf(
                 "Invoice", 
                 new { invoiceId= invoiceId }) 
                 { FileName = "Invoice.pdf" };
}

Очень очень просто

Я использую iTextSharp для создания динамических PDF-файлов в MVC. Все, что вам нужно сделать, это поместить ваш PDF-файл в объект Stream, а затем ваш ActionResult вернуть FileStreamResult. Я также установил расположение контента, чтобы пользователь мог его скачать.

public FileStreamResult PDFGenerator ()
{
    Stream fileStream = GeneratePDF ();

    HttpContext.Response.AddHeader ("Content-Disposition", 
    "attachment; filename=form.pdf");

    вернуть новый FileStreamResult(fileStream, "application/pdf");
}

У меня также есть код, который позволяет мне взять шаблон PDF, написать текст и изображения к нему и т. Д. (Если вы хотите это сделать).

  • Примечание: вы должны установить позицию потока на 0.
приватный поток GeneratePDF()
{
    // создаем ваш pdf и помещаем его в переменную stream... pdf ниже
    // происходит от класса, который я использую для записи содержимого в файлы PDF

    MemoryStream ms = new MemoryStream();

    byte[] byteInfo = pdf.Output();
    ms.Write(byteInfo, 0, byteInfo.Length);
    ms.Position = 0;

    вернуть мс;
}

Это старый вопрос, но он все еще актуален, и я подумал, что просто поделюсь тем, что я реализовал, и это хорошо работает.

  1. Установите пакет NuGet "ВайтПечкин" - форк в библиотеке Печкина на основе WkHtmlToPdf, который использует движок Webkit для преобразования HTML-страниц в PDF.

  2. Напишите небольшой помощник, чтобы прочитать представление и преобразовать его в строку HTML (mvcContext is this.HttpContext). Замена не обязательна, конечно!

    public static string RenderViewToString(HttpContextBase mvcContext, string area, string controllerName, string viewName, object model)
    {
        var context = System.Web.HttpContext.Current;
        var contextBase = mvcContext;
        var routeData = new RouteData();
        if (area == null) area = "";
    
        routeData.DataTokens.Add("area", area);
    
        routeData.Values.Add("controller", controllerName);
    
        var controllerContext = new ControllerContext(contextBase,
                                                routeData,
                                                new EmptyController());
    
        var razorViewEngine = new RazorViewEngine();
        var razorViewResult = razorViewEngine.FindView(controllerContext,
                                                    viewName,
                                                    "",
                                                false);
    
        var writer = new StringWriter();
        var viewContext = new ViewContext(controllerContext,
                                    razorViewResult.View,
                                    new ViewDataDictionary(model),
                                    new TempDataDictionary(),
                                    writer);
        razorViewResult.View.Render(viewContext, writer);
    
        string hostAddress = context.Request.Url.Scheme + "://" + context.Request.Url.Authority;
    
        return writer.ToString()
                     .Replace("src=\"/", "src=\"" + hostAddress + "/")
                     .Replace("<link href=\"/", "<link href=\"" + hostAddress + "/");                         
    }
    
    class EmptyController : ControllerBase
    {
        protected override void ExecuteCore() { }
    }
    

Тяжелая работа над этим была отсюда: http://wouterdekort.blogspot.co.uk/2012/10/rendering-aspnet-mvc-view-to-string-in.html?showComment=1414603363455

  1. Создать MVC Action для генерации документа

    public ActionResult DownloadPDF(long CentreID)
    {
        var model = GetModel()
    
        IPechkin converter = Factory.Create();
        byte[] result = converter.Convert(Helpers.PDF.RenderViewToString(this.HttpContext, "area", "controller", "action", model);
        MemoryStream outputStream = new MemoryStream();
        outputStream.Write(result, 0, result.Length);
        outputStream.Position = 0;
    
        return File(outputStream, "application/pdf", "filename.pdf");
    }
    

Создание макета в html и последующая печать в pdf - самый быстрый способ.

Преобразование HTML в PDF предоставляется http://phantomjs.org/, http://wkhtmltopdf.org/ или jsreport.

jsreport обеспечивает прямую интеграцию с представлениями asp.net mvc, где вы можете просто пометить действие контроллера с атрибутом, и он будет печатать PDF вместо HTML.

Подробнее об этом сообщении в блоге

Отказ от ответственности: я автор jsreport

Я также сталкивался с этим http://www.codeproject.com/Articles/260470/PDF-reporting-using-ASP-NET-MVC3. Это легко и быстро, и хорошо сочетается с MVC.

Тем не менее, единственным недостатком на данный момент является то, что он недостаточно гибок, вы хотите иметь приличный макет, например, у вас нет большого контроля над таблицей и границы ячеек через html. Он как бы поддерживает форсирование новой страницы, но вам придется применить патч к iTextsharp.

Я просто использовал wkhtmltopdf, чтобы создать макет в html, а затем я конвертировал его в pdf.

Легко, настраиваемо, офигенно чертовски:)

Небольшой пример использования пакета rotativa в asp.net mvc

Мы создадим функцию для заполнения данных. Мы вставим данные за 7 дней (1 февраля 2018 г. - 7 февраля 2018 г.), показывающие первый и последний удар для конкретного дня с примечаниями.

public ReportViewModel PopulateData()
        {
            var attendances = new List<Attendance>
            {
                new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 01).ToString("ddd"),Date = new DateTime(2018, 02, 01).ToString("d"),FirstPunch = "09:01:00",LastPunch = "06:00:01",Remarks = ""},
                new Attendance{ClassName = "absent",Day = new DateTime(2018, 02, 02).ToString("ddd"),Date = new DateTime(2018, 02, 02).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Absent"},
                new Attendance{ClassName = "holiday",Day = new DateTime(2018, 02, 03).ToString("ddd"),Date = new DateTime(2018, 02, 03).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Democracy Day"},
                new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 04).ToString("ddd"),Date = new DateTime(2018, 02, 04).ToString("d"),FirstPunch = "09:05:00",LastPunch = "06:30:01",Remarks = ""},
                new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 05).ToString("ddd"),Date = new DateTime(2018, 02, 05).ToString("d"),FirstPunch = "09:01:00",LastPunch = "06:00:01",Remarks = ""},
                new Attendance{ClassName = "leave",Day = new DateTime(2018, 02, 06).ToString("ddd"),Date = new DateTime(2018, 02, 06).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Sick Leave"},
                new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 07).ToString("ddd"),Date = new DateTime(2018, 02, 07).ToString("d"),FirstPunch = "08:35:00",LastPunch = "06:15:01",Remarks = ""}
            };


            return new ReportViewModel
            {
                UserInformation = new UserInformation
                {
                    FullName = "Ritesh Man Chitrakar",
                    Department = "Information Science"
                },
                StartDate = new DateTime(2018, 02, 01),
                EndDate = new DateTime(2018, 02, 07),
                AttendanceData = attendances
            };
        }

Затем мы создадим функцию для DownloadPdf. Чтобы загрузить PDF-файл, нам нужно создать 2 функции. 1. скачать pdf 2. просмотреть pdf

public ActionResult DownloadPdf()
        {
            var filename = "attendance.pdf";

            /*get the current login cookie*/
            var cookies = Request.Cookies.AllKeys.ToDictionary(k => k, k => Request.Cookies[k]?.Value);

            return new ActionAsPdf("PdfView", new
            {
                startDate = Convert.ToDateTime(Request["StartDate"]),
                endDate = Convert.ToDateTime(Request["EndDate"])
            })
            {
                FileName = filename,
                /*pass the retrieved cookie inside the cookie option*/
                RotativaOptions = {Cookies = cookies}
            };
        }

public ActionResult PdfView()
        {
            var reportAttendanceData = PopulateData();

            return View(reportAttendanceData);
        }

Вы можете просмотреть подробное объяснение по этой ссылке. Посетите здесь.

Куртесой: https://www.thelearninguy.com/

Очень поздний ответ, но я обнаружил, что следующий URL помог мне быстро получить результаты:

(Убедитесь, что вы ссылаетесь на библиотеку iTextSharp, используя пакеты Nuget)

https://www.aspsnippets.com/Articles/Export-Grid-Html-Table-data-from-database-to-PDF-file-using-iTextSharp-in-ASPNet-MVC.aspx

РЕДАКТИРОВАТЬ Это код, который я использовал, чтобы таблица выглядела немного иначе (Это также пейзаж:

public string GetCssForPdf()
        {
            string css = "";

            css = "th, td" +
                   "{" +
                       "font-family:Arial; font-size:10px" +
                    "}";

            return css;
        }

[HttpPost]
        [ValidateInput(false)]
        public FileResult Export(string GridHtml)
        {
            string webgridstyle = GetCssForPdf();

            string exportData = String.Format("<html><body>{0}{1}</body></html>", "<style>" + webgridstyle + "</style>", GridHtml);
            var bytes = System.Text.Encoding.UTF8.GetBytes(exportData);

            using (var input = new MemoryStream(bytes))
            {
                var output = new MemoryStream();
                var document = new iTextSharp.text.Document(PageSize.A4, 50, 50, 50, 50);
                var writer = PdfWriter.GetInstance(document, output);

                document.SetPageSize(iTextSharp.text.PageSize.A4.Rotate());
                Font headerFont = FontFactory.GetFont("Verdana", 10);
                Font rowfont = FontFactory.GetFont("Verdana", 10);

                writer.CloseStream = false;
                document.Open();

                var xmlWorker = iTextSharp.tool.xml.XMLWorkerHelper.GetInstance();
                xmlWorker.ParseXHtml(writer, document, input, System.Text.Encoding.UTF8);
                document.Close();
                output.Position = 0;

                return File(output, "application/pdf", "Pipeline_Report.pdf");

                //return new FileStreamResult(output, "application/pdf");
            }
        }

Надеюсь, это поможет кому-то еще.

Другие вопросы по тегам