在应用样式和脚本后,如何生成MVC视图的PDF

时间:2014-11-11 10:53:03

标签: c# asp.net-mvc pdf-generation phantomjs wkhtmltopdf

我想从包含styes和脚本的视图中打印PDF文档。在应用脚本和样式后,我如何阅读整个视图的html。 它应该在运行javascript,JQuery,Angular等脚本之后返回html。

示例是在页面上加载jquery ajax post和fill tables。以下是在没有填充表的情况下运行javascript函数之前返回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();
        }
    }

我希望获得完整的java脚本呈现页面html,如浏览器页面HTML

1 个答案:

答案 0 :(得分:0)

Razor / ASP.Net只生成源,而不是执行客户端脚本。您需要使用模拟Web浏览器的内容将客户端脚本转换为呈现的PDF。

这意味着它需要理解脚本和样式(即就像浏览器一样)。

有几种商业产品,但我个人使用Essential Objects PDF转换器直接生成PDF视图。它有一个内置的Javascript引擎,所以看起来就像在浏览器中一样。

请注意,这些产品非常复杂(因为它们包含完整的浏览器渲染引擎),因此大多数都需要付费许可证(至少用于商业用途)。

资料来源: How to generate PDF from HTML view after scripts and styles applied in ASP.NET MVC

在稿件和样式发布后生成PDF

用于生成javascript和样式渲染视图或html页面的最佳工具是phantomJS。

使用在示例文件夹的exe的根目录中找到的rasterize.js函数下载.exe文件并将其放入解决方案中。

以下代码生成PDF文件:

public ActionResult DownloadHighChartHtml()
    {
        string serverPath = Server.MapPath("~/phantomjs/");
        string filename = DateTime.Now.ToString("ddMMyyyy_hhmmss") + ".pdf";
        string Url = "http://stagebelweb.azurewebsites.net/race/16867";

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