2013-10-28 8 views
8

phantomJS'yi inceliyorum ve PDF oluşturmayı kullanmak için harika bir araç olabilir. Herkesin .NET uygulamaları için başarıyla kullandığını merak ediyorum..NET uygulamalarında Phantom JS kullanarak PDF oluşturma

Özel sorum şu: sunucuda rasterize.js gibi modülleri nasıl kullanırsınız, istekleri alırsınız ve yanıt olarak oluşturulmuş pdfs'leri geri gönderirsiniz.

Genel sorum şu: .NET Uygulamaları ile phantomJS'yi kullanmak için en iyi yöntem var mı? Bunu başarmanın en iyi yolu ne olurdu?

.NET World'te oldukça yeni ve daha ayrıntılı yanıtları takdir ediyorum. Herkese teşekkürler. :)

cevap

13

Ben en iyi uygulamalar hakkında bilmiyorum görüyorum ama olabilir.

kullanıcı tıkladığında DownloadStatement Action için bir bağlantıyı: Burada

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

eylem akışıdır. Orada, ExecuteCommand yöntemini çağırmak için yeni bir Thread oluşturulur.

ExecuteCommand yöntemi phantomJS'yi çağırmaktan sorumludur. Bir argüman olarak iletilen dize aşağıdakileri yapar.

phantomJS uygulamasının olduğu konuma gidin ve bundan sonra URL ile rasterize.js'u, oluşturulacak dosya adını ve bir yazdırma biçimini arayın. (More about rasterize here).

Benim durumumda, gerçekten basmak istediklerim, action dosya yükleme tarafından sağlanan içeriktir. Basit bir görünüm kazandıran basit bir işlemdir. PhantomJS, parametre olarak geçirilen URL'yi çağırır ve tüm sihirleri yapar.

phantomJS dosyası hala oluşturulurken (sanırım) istemcinin yaptığı isteği geri alamıyorum. Ve bu yüzden DoWhile yöntemini kullandım. Dosya phantomJS tarafından oluşturulana ve istek üzerine uygulama tarafından yüklenene kadar isteği tutacaktır.

+0

Teşekkürler Felipe. Bu harika. – Balash

+4

Bir while while döngüsü yerine Process.WaitForExit öğesini kullanabilirsiniz. http://msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx –

+0

Uygulama, Windows Server 2008+ üzerinde IIS'de çalıştırıldığında çalışmaz. Bu çözüm, görsel stüdyosundan test ettiğinizde çalışır, ancak IIS'ye dağıtıldığında üretimde çalışmayacaktır, 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(); 
}); 

Sen Aşağıdaki kod ile hiçbir sorunları olan phantomJS kullanıyorum Burada bir örnek Capture screen of webpage in different formats

+5

Bu, sorulan soruya verilen yanıtın değil. – Motes

1

Eğer PhantomJS için bir .NET sarıcı sağlayan NReco.PhantomJS açıksa, bunu çok kısa bir sürede yapabilirsiniz.

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