Asp.Net MVC how to get view to generate PDF

前端 未结 8 1494
醉酒成梦
醉酒成梦 2020-11-28 19:09

I would like to call an action on a controller. Have the controller get the data from the model. The view then runs and generates a PDF. The only example I have found i

相关标签:
8条回答
  • 2020-11-28 19:46

    Creating layout in html and printing afterwards into pdf is the fastest way.

    Html into pdf conversion is provided by phantomjs, wkhtmltopdf or jsreport

    jsreport provides direct integration with asp.net mvc views, where you can just mark controller action with attribute and it will print pdf instead of html for you.

    More on this blog post

    Disclaimer: I am the author of jsreport

    0 讨论(0)
  • 2020-11-28 19:47

    This is an old question but one that's still relevant and I thought I'd just share what I've implemented which works well.

    1. Install NuGet package TuesPechkin - a fork in the Pechkin library based on WkHtmlToPdf that uses a Webkit engine to convert HTML pages to PDF.

    2. Write a little helper to read a view and convert it to an HTML string (mvcContext is this.HttpContext). The replace is optional of course!:

      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() { }
      }
      

    The hard work of the above were from here: http://wouterdekort.blogspot.co.uk/2012/10/rendering-aspnet-mvc-view-to-string-in.html?showComment=1414603363455#c7863520150405064571

    1. Create an MVC Action to generate the document

      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");
      }
      
    0 讨论(0)
  • 2020-11-28 19:54

    A small example using rotativa package in asp.net mvc

    We will create a function to populate the data. We will insert data for 7 days (Feb 1 2018 - Feb 7 2018) showing the first punch and the last punch for particular day with remarks.

    public ReportViewModel PopulateData()
            {
                var attendances = new List<Attendance>
                {
                    new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 01).ToString("ffffd"),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("ffffd"),Date = new DateTime(2018, 02, 02).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Absent"},
                    new Attendance{ClassName = "holiday",Day = new DateTime(2018, 02, 03).ToString("ffffd"),Date = new DateTime(2018, 02, 03).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Democracy Day"},
                    new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 04).ToString("ffffd"),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("ffffd"),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("ffffd"),Date = new DateTime(2018, 02, 06).ToString("d"),FirstPunch = "",LastPunch = "",Remarks = "Sick Leave"},
                    new Attendance{ClassName = "present",Day = new DateTime(2018, 02, 07).ToString("ffffd"),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
                };
            }
    

    We will then create a function to DownloadPdf. To download the pdf we will need to create 2 function. 1. to download pdf 2. to view 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);
            }
    

    You can view the detail explanation on this link . Visit here .

    Curtesoy : thelearninguy.com

    0 讨论(0)
  • 2020-11-28 19:59

    our final answer to this problem was to use Rotativa.

    It wraps up the WKhtmltopdf.exe like some of the other solutions, but it's by far the easiest to use that I have found

    I went and up voted all the other answers that also solve the problem well, but this is what we used to solve the problem posed in the question above. It is different from the other answers.

    Here is a Rotativa Tutorial.

    after you install it, this is all your need

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

    Very Very simple.

    0 讨论(0)
  • 2020-11-28 20:01

    I also came across this http://www.codeproject.com/Articles/260470/PDF-reporting-using-ASP-NET-MVC3. It's easy and swift, and fits well with MVC.

    However, the only downside so far is that it's not quite flexible you want to have a decent layout, for example, you don't have much control with table, and cell borders through html. It sort of supports force new page, but you will have to apply a patch to iTextsharp.

    0 讨论(0)
  • 2020-11-28 20:02

    I use iTextSharp to generate dynamic PDF's in MVC. All you need to do is put your PDF into a Stream object and then your ActionResult return a FileStreamResult. I also set the content-disposition so the user can download it.

    public FileStreamResult PDFGenerator()
    {
        Stream fileStream = GeneratePDF();
    
        HttpContext.Response.AddHeader("content-disposition", 
        "attachment; filename=form.pdf");
    
        return new FileStreamResult(fileStream, "application/pdf");
    }
    

    I also have code that enables me to take a template PDF, write text and images to it etc (if you wanted to do that).

    • Note: you must set the Stream position to 0.
    private Stream GeneratePDF()
    {
        //create your pdf and put it into the stream... pdf variable below
        //comes from a class I use to write content to PDF files
    
        MemoryStream ms = new MemoryStream();
    
        byte[] byteInfo = pdf.Output();
        ms.Write(byteInfo, 0, byteInfo.Length);
        ms.Position = 0;
    
        return ms;
    }
    
    0 讨论(0)
提交回复
热议问题