asp.net-mvc Asp.Net MVC 如何获取视图以生成 PDF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/779430/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:31:20  来源:igfitidea点击:

Asp.Net MVC how to get view to generate PDF

asp.net-mvcpdf

提问by Eric Brown - Cal

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 is in an article by Lou http://whereslou.com/2009/04/12/returning-pdfs-from-an-aspnet-mvc-action. His code is very elegant. The view is using ITextSharp to generate the PDF. The only downside is his example uses the Spark View Engine. Is there a way to do a similar thing with the standard Microsoft view engine?

我想在控制器上调用一个动作。让控制器从模型中获取数据。然后该视图运行并生成一个 PDF。我发现的唯一例子是 Lou http://whereslou.com/2009/04/12/returning-pdfs-from-an-aspnet-mvc-action的一篇文章。他的代码非常优雅。该视图使用 ITextSharp 生成 PDF。唯一的缺点是他的示例使用了 Spark 视图引擎。有没有办法用标准的 Microsoft 视图引擎做类似的事情?

采纳答案by Eric Brown - Cal

our final answer to this problem was to use Rotativa.

我们对这个问题的最终答案是使用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

它像其他一些解决方案一样包含 WKhtmltopdf.exe,但它是迄今为止我发现的最容易使用的

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.

这是一个Rotativa 教程

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.

非常非常简单。

回答by David

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.

我使用 iTextSharp 在 MVC 中生成动态 PDF。您需要做的就是将您的 PDF 放入一个 Stream 对象,然后您的 ActionResult 返回一个 FileStreamResult。我还设置了 content-disposition 以便用户可以下载它。

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).

我还有一些代码,使我能够获取模板 PDF、向其中写入文本和图像等(如果您想这样做的话)。

  • Note: you must set the Stream position to 0.
  • 注意:您必须将 Stream 位置设置为 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;
}

回答by Jan Blaha

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

在 html 中创建布局然后打印成 pdf 是最快的方法。

Html into pdf conversion is provided by phantomjs, wkhtmltopdfor jsreport

Html 到 pdf 的转换由phantomjs, wkhtmltopdfjsreport 提供

jsreportprovides 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.

jsreport提供与 asp.net mvc 视图的直接集成,您可以在其中使用属性标记控制器操作,它会为您打印 pdf 而不是 html。

More on this blog post

关于这篇博文的更多信息

Disclaimer: I am the author of jsreport

免责声明:我是 jsreport 的作者

回答by McGaz

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() { }
    }
    
  1. 安装 NuGet 包 TuesPechkin - 基于 WkHtmlToPdf 的 Pechkin 库中的一个分支,它使用 Webkit 引擎将 HTML 页面转换为 PDF。

  2. 编写一个小助手来读取视图并将其转换为 HTML 字符串(mvcContext 就是 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() { }
    }
    

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

以上的辛勤工作来自这里: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");
    }
    
  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");
    }
    

回答by Sean Dong

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.

我也遇到了这个http://www.codeproject.com/Articles/260470/PDF-reporting-using-ASP-NET-MVC3。它简单快捷,非常适合 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.

然而,到目前为止唯一的缺点是它不是很灵活,你想要一个像样的布局,例如,你没有太多的表格控制,通过 html 单元格边框。它有点支持强制新页面,但您必须对 iTextsharp 应用补丁。

回答by NicoJuicy

I just used wkhtmltopdf, to create the layout in html and afterwards, i convert it to pdf.

我只是使用 wkhtmltopdf,在 html 中创建布局,然后将其转换为 pdf。

Easy, customizable, awesome as hell :)

简单,可定制,真棒:)

回答by AxleWack

Very Late Reply, but I found that the following URL helped me get my results quickly :

很晚的回复,但我发现以下 URL 帮助我快速获得了结果:

(Ensure that you reference to the iTextSharp DLL by making use of the Nuget Packages)

(确保您通过使用 Nuget 包来引用 iTextSharp DLL)

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

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

EDITThis is the code I used to make the table look a little different(This is landscape as well:

编辑这是我用来使表格看起来有点不同的代码(这也是风景:

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");
            }
        }

Hope this helps someone else as well.

希望这对其他人也有帮助。

回答by Ritesh Chitrakar

A small example using rotativa package in asp.net mvc

在asp.net mvc中使用rotativa包的一个小例子

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.

我们将创建一个函数来填充数据。我们将插入 7 天(2018 年 2 月 1 日 - 2018 年 2 月 7 日)的数据,显示特定日期的第一次打卡和最后一次打卡,并附有备注。

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
            };
        }

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

然后,我们将为 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);
        }

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

您可以在此链接上查看详细说明。访问这里

Curtesoy : thelearninguy.com

Curtesoy : thelearninguy.com