简体   繁体   English

如何在ASP.NET MVC中应用脚本和样式后从HTML视图生成PDF

[英]How to generate PDF from HTML view after scripts and styles applied in ASP.NET MVC

I want to generate HTML of my View to generate PDF document. 我想生成View的HTML以生成PDF文档。 It has styles and scripts applied when it opens in browser. 它在浏览器中打开时具有应用的样式和脚本。 I tried the following code but it only gives the html of view before scripts modifications. 我尝试了以下代码,但在脚本修改之前它仅提供了视图的html。 I need to get HTML of view after scripts modifications like text changed same as browser. 在脚本修改(如文本更改)与浏览器相同之后,我需要获取视图的HTML。

public string RenderRazorViewToString(string viewName, object model)
{
        ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext,
                                                                     viewName);
            var viewContext = new ViewContext(ControllerContext, viewResult.View,
                                         ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);
            viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
            return sw.GetStringBuilder().ToString();
        }
}

I might as well post my comment as an answer... 我不妨发表评论作为答案...

Razor/ASP.Net will only generate source, not execute client-side scripts. Razor / ASP.Net将仅生成源,而不执行客户端脚本。 You need to use something that emulates a web browser to turn the client-side script into a rendered PDF. 您需要使用模仿网络浏览器的工具来将客户端脚本转换为渲染的PDF。

That means it needs to understand both script and styling (ie just like a browser). 这意味着它需要同时了解脚本样式 (即就像浏览器一样)。

There are several commercial products out there, but I have personally used Essential Objects PDF converter to generate views direct to PDF. 那里有几种商业产品,但是我亲自使用了Essential Objects PDF转换器来直接生成PDF视图。 It has a built-in Javascript engine, so looks just like it will in the browser. 它具有内置的Javascript引擎,因此看起来就像在浏览器中一样。

Please note these products are very complex (as they include complete Browser rendering engines), so most will required paid licences (for commercial use at least). 请注意,这些产品非常复杂(因为它们包含完整的浏览器渲染引擎),因此大多数将需要付费许可(至少用于商业用途)。

Note: I am in no way associated with Essential Objects. 注意:我绝不与基本对象相关联。 This is purely opinion based on actual use of that product. 这纯粹是基于该产品的实际使用的意见。

Best Tool i have found and used for generating PDF of javascript and styles rendered views or html pages is phantomJS . 我发现并用于生成javascript和样式的PDF渲染视图或html页面的最佳工具是phantomJS

Download the .exe file with the rasterize.js function found in root of exe of example folder and put inside solution. 使用在示例文件夹的exe根目录中找到的rasterize.js函数下载.exe文件,并将其放入解决方案中。

Following code generate PDF File : 以下代码生成PDF文件:

 public ActionResult DownloadHighChartHtml()
    {
        string serverPath = Server.MapPath("~/phantomjs/");
        string filename = DateTime.Now.ToString("ddMMyyyy_hhmmss") + ".pdf";
        string Url = "http://wwwabc.com";

        new Thread(new ParameterizedThreadStart(x =>
        {
            ExecuteCommand(string.Format("cd {0} & E: & phantomjs rasterize.js {1} {2} \"A4\"", serverPath, Url, filename));
                               //E: is the drive for server.mappath
        })).Start();

        var filePath = Path.Combine(Server.MapPath("~/phantomjs/"), filename);

        var stream = new MemoryStream();
        byte[] bytes = DoWhile(filePath);

        Response.ContentType = "application/pdf";
        Response.AddHeader("content-disposition", "attachment;filename=Image.pdf");
        Response.OutputStream.Write(bytes, 0, bytes.Length);
        Response.End();
        return RedirectToAction("HighChart");
    }



    private void ExecuteCommand(string Command)
    {
        try
        {
            ProcessStartInfo ProcessInfo;
            Process Process;

            ProcessInfo = new ProcessStartInfo("cmd.exe", "/K " + Command);

            ProcessInfo.CreateNoWindow = true;
            ProcessInfo.UseShellExecute = false;

            Process = Process.Start(ProcessInfo);
        }
        catch { }
    }


    private byte[] DoWhile(string filePath)
    {
        byte[] bytes = new byte[0];
        bool fail = true;

        while (fail)
        {
            try
            {
                using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    bytes = new byte[file.Length];
                    file.Read(bytes, 0, (int)file.Length);
                }

                fail = false;
            }
            catch
            {
                Thread.Sleep(1000);
            }
        }

        System.IO.File.Delete(filePath);
        return bytes;
    }

If you want user to download the pdf of rendered page then the easiest solution to the problem is 如果您希望用户下载渲染页面的pdf,那么最简单的解决方法是

window.print(); 

on client side it will prompt user to save pdf of current page. 在客户端,它将提示用户保存当前页面的pdf。 You can also customize the appearance of pdf by linking style 您还可以通过链接样式来自定义pdf的外观

<link rel="stylesheet" type="text/css" href="print.css" media="print">

print.css is applied to the html while printing. 打印时将print.css应用于html。

Limitation 局限性

  1. You can't store the file on server side. 您不能在服务器端存储文件。
  2. User prompt to print the page than he had to save page manually. 用户提示要打印页面,而不是手动保存页面。
  3. Page must to be rendered in a tab. 页面必须在选项卡中呈现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM