Ich weiß nicht, über die besten Praktiken, aber ich bin mit PhantomJS ohne Probleme mit dem folgenden 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;
}
Hier ist die Wirkungsablauf:
Der Benutzer klickt auf einen Link zu DownloadStatement Action
. Dort wird eine neue Thread
erstellt, um die Methode ExecuteCommand
aufzurufen.
Die Methode ExecuteCommand
ist dafür verantwortlich, phantomJS aufzurufen. Die als Argument übergebene Zeichenfolge führt Folgendes aus.
Gehen Sie zum Speicherort der phantomJS-App und rufen Sie anschließend rasterize.js
mit einer URL, dem zu erstellenden Dateinamen und einem Druckformat auf. (More about rasterize here).
In meinem Fall, was ich wirklich drucken möchte, ist der Inhalt von action
Filetoupload geliefert. Es ist eine einfache Aktion, die eine einfache Ansicht zurückgibt. PhantomJS wird die als Parameter übergebene URL aufrufen und all die Magie vollbringen.
Während phantomJS immer noch die Datei erstellt, (ich schätze) kann ich die Anfrage des Clients nicht zurückgeben. Und deshalb habe ich die DoWhile
Methode verwendet. Es wird die Anfrage halten, bis die Datei von phantomJS erstellt und von der App auf die Anfrage geladen wird.
Danke Felipe. Das ist toll. – Balash
Sie könnten Process.WaitForExit anstelle einer do while-Schleife verwenden. http://msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx –
Das funktioniert nicht, wenn die Anwendung in IIS unter Windows Server 2008+ ausgeführt wird. Diese Lösung funktioniert, wenn Sie sie aus Visual Studio testen, aber nicht in der Produktion funktionieren, wenn sie in IIS bereitgestellt wird, http://StackOverflow.com/a/5308011/1062224. –