我不知道最佳实践,但是,我正在使用 phantomJS,下面的代码没有问题。
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 的链接。在其中,创建了一个新的Thread 来调用ExecuteCommand 方法。
ExecuteCommand 方法负责调用 phantomJS。作为参数传递的字符串执行以下操作。
转到 phantomJS 应用程序所在的位置,然后使用 URL、要创建的文件名和打印格式调用 rasterize.js。 (More about rasterize here)。
就我而言,我真正想要打印的是action filetoupload 提供的内容。这是一个返回简单视图的简单操作。 PhantomJS 将调用作为参数传递的 URL 并执行所有魔术。
虽然 phantomJS 仍在创建文件,(我猜)我无法返回客户端发出的请求。这就是我使用DoWhile 方法的原因。它将保留请求,直到文件由 phantomJS 创建并由应用程序加载到请求。