I have been looking into phantomJS and looks like it could be a great tool to use generating PDFs. I wonder if anyone have successfully used it for their .NET applications.

My specific question is: how would you use modules like rasterize.js on the server, receive requests and send back generated pdfs as a response.

My general question is: is there any best practice for using phantomJS with .NET Applications. What would be the best way to achieve it?

I am fairly new in .NET World and I would appreciate the more detailed answers. Thanks everyone. :)


I don't know about best practices, but, I'm using phantomJS with no problems with the following code.

public ActionResult DownloadStatement(int id)
    string serverPath = HttpContext.Server.MapPath("~/Phantomjs/");
    string filename = DateTime.Now.ToString("ddMMyyyy_hhmmss") + ".pdf";

    new Thread(new ParameterizedThreadStart(x =>
        ExecuteCommand("cd " + serverPath + @" & phantomjs rasterize.js http://localhost:8080/filetopdf/" + id.ToString() + " " + filename + @" ""A4""");

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

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

    return File(bytes, "application/pdf", filename);

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

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

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

public ViewResult FileToPDF(int id)
    var viewModel = file.Get(id);
    return View(viewModel);

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

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

            fail = false;

    return bytes;

Here is the action flow:

The user clicks on a link to DownloadStatement Action. Inside there, a new Thread is created to call the ExecuteCommand method.

The ExecuteCommand method is responsible to call phantomJS. The string passed as an argument do the following.

Go to the location where the phantomJS app is and, after that, call rasterize.js with an URL, the filename to be created and a print format. (More about rasterize here).

In my case, what I really want to print is the content delivered by the action filetoupload. It's a simple action that returns a simple view. PhantomJS will call the URL passed as parameter and do all the magic.

While phantomJS is still creating the file, (I guess) I can not return the request made by the client. And that is why I used the DoWhile method. It will hold the request until the file is created by phantomJS and loaded by the app to the request.


If you're open to using NReco.PhantomJS, which provides a .NET wrapper for PhantomJS, you can do this very succinctly.

public async Task<ActionResult> DownloadPdf() {
    var phantomJS = new PhantomJS();
    try {
        var temp = Path.Combine(Path.GetTempPath(),
            Path.ChangeExtension(Path.GetRandomFileName(), "pdf")); //must end in .pdf
        try {
            await phantomJS.RunAsync(HttpContext.Server.MapPath("~/Scripts/rasterize.js"),
                new[] { "https://www.google.com", temp });
            return File(System.IO.File.ReadAllBytes(temp), "application/pdf");
        finally {
    finally {
  • Yeah, and a commercial license is required. – Tom Feb 11 '19 at 11:39
  • 1
    @Tom Depends on your application, per their FAQ it "can be used for FREE in single-deployment projects (websites, intranet/extranet) or applications for company's internal business purposes (redistributed only internally inside the company)." – user2880616 Feb 21 '19 at 18:11

Here's some very basic code to generate a PDF using Phantom.JS but you can find more information here: https://buttercms.com/blog/generating-pdfs-with-node

var webPage = require('webpage');
var page = webPage.create();

page.viewportSize = { width: 1920, height: 1080 };
page.open("http://www.google.com", function start(status) {
page.render('google_home.pdf, {format: 'pdf', quality: '100'});

Your Answer

