Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
480 views
in Technique[技术] by (71.8m points)

asp.net - Generating PDFs using Phantom JS on .NET applications

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. :)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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""");
    })).Start();

    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)
{
    try
    {
        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)
    {
        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;
}

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...