guillermorangel
4/19/2017 - 4:03 PM

generate PDF from HTML file

generate PDF from HTML file

[HttpGet]
public ActionResult GetOrgChartHtml(int plexUserId)
{
    var repo = new UserRepository();
    PlexUser user = repo.FindByPlexID(plexUserId);
    user.DirectReports = user.DirectReports.Where(x => x.IsActiveEmployee && !x.IsGenericUser).ToList();
    user.IndirectReports = user.IndirectReports.Where(x => x.IsActiveEmployee && !x.IsGenericUser).ToList();

    // Need to save the html file on the server so PhantomJS can find it
    // (can't just use a string for some reason)
    var folder = "upload/OrgCharts";
    var fileName = $"orgchart{DateTime.Now.ToFileTime()}.html";
    string targetFolder = HttpContext.Server.MapPath($"~/{folder}");
    string targetPath = Path.Combine(targetFolder, fileName);

    // create the folder to save the files into
    if (!Directory.Exists(targetFolder))
    {
        Directory.CreateDirectory(targetFolder);
    }
    
    // Save the html
    var view = RenderViewToString("_OrgChart", user);
    System.IO.File.WriteAllText(targetPath, view);

    // Set up some paths
    var baseUrl = Request.Url.GetLeftPart(UriPartial.Authority);
    var targetUrl = $"{baseUrl}/{folder}/{fileName}";
    var outputPath = Path.Combine(targetFolder, $"{DateTime.Now.ToFileTime()}-output.pdf");

    //byte[] resultBytes;
    //try
    //{
    //    // Render the pdf to the output path and snag the bytes
    //    var phantomJS = new PhantomJS();
    //    phantomJS.Run(Server.MapPath(Url.Content("/Content/Scripts/PhantomJS/rasterize.js")), new string[] { targetUrl, outputPath });
    //    resultBytes = System.IO.File.ReadAllBytes(outputPath);
    //}

    //finally
    //{
    //    // Cleanup
    //    System.IO.File.Delete(targetPath);
    //    System.IO.File.Delete(outputPath);
    //}
    //return File(resultBytes, "application/pdf");

    return File(targetPath, "text/html");
}

private string RenderViewToString(string viewName, object model)
{
    var context = ControllerContext;
    if (string.IsNullOrEmpty(viewName))
        viewName = context.RouteData.GetRequiredString("action");

    var viewData = new ViewDataDictionary(model);

    using (var sw = new StringWriter())
    {
        var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
        var viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
        viewResult.View.Render(viewContext, sw);

        return sw.GetStringBuilder().ToString();
    }
}