2013-10-28 17 views
8

私はphantomJSを探していて、それはPDFの生成を使用する素晴らしいツールであるようです。私は誰もが正常に彼らの.NETアプリケーションのためにそれを使用しているのだろうか。.NETアプリケーションでPhantom JSを使用してPDFを生成

私の具体的な質問は、サーバ上でrasterize.jsのようなモジュールを使ってリクエストを受信し、生成されたpdfsを応答としてどのように返すかということです。

私の一般的な質問は、.NETアプリケーションでphantomJSを使用するためのベストプラクティスですか?それを達成する最良の方法は何でしょうか?

.NETの世界ではかなり新しく、より詳細な回答に感謝します。みんな、ありがとう。 :)

答えて

13

を例を見ることができます。ここで

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; 
} 

は、アクションの流れです:

ユーザーがDownloadStatement Actionへのリンクをクリックします。その内部にはExecuteCommandメソッドを呼び出すための新しいThreadが作成されています。

ExecuteCommandメソッドは、phantomJSを呼び出す責任があります。引数として渡される文字列は次のようになります。

phantomJSアプリがある場所に移動し、その後、URL、作成するファイル名、および印刷書式でrasterize.jsを呼び出します。 (More about rasterize here)。

私が実際に印刷したいのは、actionファイルのアップロードによって配信されるコンテンツです。これはシンプルな操作で、簡単なビューを返します。 PhantomJSはパラメータとして渡されたURLを呼び出し、すべての魔法を実行します。

phantomJSは依然としてファイルを作成していますが(私は推測しますが)、クライアントからの要求は返せません。それが私がDoWhileメソッドを使用した理由です。これは、ファイルがphantomJSによって作成され、アプリケーションによって要求にロードされるまで要求を保持します。

+0

ありがとうフェリペ。これは素晴らしい。 – Balash

+4

do whileループの代わりにProcess.WaitForExitを使用できます。 http://msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx –

+0

アプリケーションがWindows Server 2008以降のIISで実行されている場合、これは機能しません。このソリューションは、Visual Studioからテストするときに機能しますが、IISにデプロイされたときは本番環境では動作しません。http://stackoverflow.com/a/5308011/1062224 –

-2
var page = require('webpage').create(); 
page.open('http:/www.google.com', function() { 

page.render('c:\test.pdf'); 
phantom.exit(); 
}); 

あなたは私がベストプラクティスについては知らないが、私は次のコードで問題なくphantomJSを使用していますここCapture screen of webpage in different formats

+5

これは質問された質問に対する回答ではありません。 – Motes

1

PhantomJSの.NETラッパーを提供するNReco.PhantomJSを使用している場合は、これを非常に簡潔に行うことができます。

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 { 
      System.IO.File.Delete(temp); 
     } 
    } 
    finally { 
     phantomJS.Abort(); 
    } 
} 
関連する問題