Search code examples
c#asp.netasp.net-mvc-3asp.net-mvc-4abcpdf

Manipulate a MVC4 view's DOM and generate a CSS formatted PDF


first of all the current state:

  • I have a MVC4 webapplication (online calculator) with razor engine
  • the application has a resultview which shows the calculated results
  • I have the abbility to use ABCPDF 8.1
  • To manipulate DOM I use the HtmlAgilityPack

The goal is: inside the ResultController, get the current views html, manipulate its DOM (especially remove navigation elements) and generate a fully formatted pdf.

Following things work:

Create a fully css styled pdf from a URL

var document  = new Doc();
document.AddImageUrl("www.whatever.com");
return File(doc.GetData(), "application/pdf", "abc.pdf");

Create a pdf from a views html with manipulated DOM without the specific CSS3 formattings

using (StringWriter sw = new StringWriter())
{

    // get html stream from view
    var result = ViewEngines.Engines.FindView(ControllerContext, "WizardFirstStep", "_Layout");
    var context = new ViewContext(ControllerContext, result.View, ViewData, TempData, sw);
    result.View.Render(context, sw);
    var html = sw.ToString();

    // manipulate DOM with HtmlAgilityPack
    var hdoc = new HtmlDocument();
    hdoc.LoadHtml(html);
    ... manipulation

    // create pdf and return FileContentResult
    var doc = new Doc();
    doc.AddImageHtml(hdoc.DocumentNode.InnerHtml);
    return File(doc.GetData(), "application/pdf", "abc.pdf");
}

So I can create a styled html site as pdf and i can create a manipulated non-styled html file as pdf.

AddImageUrl uses css

AddImageHtml doesn't use the css

I'll be glad about every approach and solution

//edit:

I have a quick workaround for this problem. Instead of @Styles.Render the css relative with

@Styles.Render("~/Content/css")

I absolutely address the stylesheet

@Styles.Render("http://localhost:53406/Content/Site.css")

But maybe there are other solutions.


Solution

  • Since this is MVC and everything can be controlled through URL, I say load the document as a URL rather than an image.

    theDoc.AddImageUrl("http://www.google.com/")
    

    This way ABCpdf loads the page the way you see it. Unless there are scripts and whatnot that control the view, then you'd need to configure the document for that.