2

I want to generate HTML of my View to generate PDF document. 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. I need to get HTML of view after scripts modifications like text changed same as browser.

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();
        }
}
Shan Khan
  • 9,667
  • 17
  • 61
  • 111
  • Then you should have taken note of my comment on the first (now deleted) question! –  Nov 11 '14 at 11:52
  • yes you told javascript runs on server. but if the view has angular directive and templates binded with the view. and how i can generate pdf from the view. isnt there any way then to generate html after scripts running ? – Shan Khan Nov 11 '14 at 11:55
  • Razor will only generate source, not execute *client-side* scripts. We use a product called EO.pdf to generate PDFs, as it emulates a browser and renders after scripts have run. – iCollect.it Ltd Nov 11 '14 at 11:57

3 Answers3

1

I might as well post my comment as an answer...

Razor/ASP.Net will only generate source, not execute client-side scripts. You need to use something that emulates a web browser to turn the client-side script into a rendered PDF.

That means it needs to understand both script and styling (i.e. 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. It has a built-in Javascript engine, so looks just like it will in the browser.

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.

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
  • i have found wkHTMLtopdf , it some how shows the styles one step ahead when compared to iTextSharp, spirenet but still doenst render scripts. any free library would be nice. Thanks – Shan Khan Nov 11 '14 at 16:26
0

Best Tool i have found and used for generating PDF of javascript and styles rendered views or html pages is phantomJS.

Download the .exe file with the rasterize.js function found in root of exe of example folder and put inside solution.

Following code generate PDF File :

 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;
    }
Shan Khan
  • 9,667
  • 17
  • 61
  • 111
-1

If you want user to download the pdf of rendered page then the easiest solution to the problem is

window.print(); 

on client side it will prompt user to save pdf of current page. You can also customize the appearance of pdf by linking style

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

print.css is applied to the html while printing.

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.
Ravi Kumar Mistry
  • 1,063
  • 1
  • 13
  • 24
  • i think that might not be a answer that will run when the user opens the page , i dont want to user to open page just download the page automatically. – Shan Khan Mar 18 '15 at 10:03
  • I mentioned it in the limitation in my answer too. – Ravi Kumar Mistry Mar 18 '15 at 10:28
  • @shan put an ancher to actual page for which you want to genrate pdf, turn off the visibilty of the page body by css so user can not see the page and override the body style in print.css so page content can be in pdf and add the script on page window.print() on load and user never know that page is opened at all. the solution is very fast and easy – Ravi Kumar Mistry Mar 18 '15 at 10:40