8

我一直在研究 phantomJS,看起来它可能是使用生成 PDF 的好工具。我想知道是否有人成功地将它用于他们的 .NET 应用程序。

我的具体问题是:您将如何在服务器上使用像rasterize.js这样的模块,接收请求并将生成的 pdf 作为响应发回。

我的一般问题是:在 .NET 应用程序中使用 phantomJS 是否有任何最佳实践。实现它的最佳方法是什么?

我在 .NET World 中相当新,我会很感激更详细的答案。感谢大家。:)

4

3 回答 3

13

我不知道最佳实践,但是,我正在使用 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 应用程序所在的位置,然后rasterize.js使用 URL、要创建的文件名和打印格式进行调用。(更多关于光栅化在这里)。

就我而言,我真正想要打印的是actionfiletoupload 传递的内容。这是一个返回简单视图的简单操作。PhantomJS 将调用作为参数传递的 URL 并执行所有魔术。

虽然 phantomJS 仍在创建文件,(我猜)我无法返回客户端发出的请求。这就是我使用这种DoWhile方法的原因。它将保留请求,直到文件由 phantomJS 创建并由应用程序加载到请求。

于 2013-11-12T15:58:23.980 回答
1

如果你愿意使用NReco.PhantomJS,它为 PhantomJS 提供了一个 .NET 包装器,你可以非常简洁地做到这一点。

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();
    }
}
于 2017-06-16T22:26:30.323 回答
0

这是使用 Phantom.JS 生成 PDF 的一些非常基本的代码,但您可以在此处找到更多信息:https ://buttercms.com/blog/generating-pdfs-with-node

var webPage = require('webpage');
var page = webPage.create();

page.viewportSize = { width: 1920, height: 1080 };
page.open("http://www.google.com", function start(status) {
page.render('google_home.pdf, {format: 'pdf', quality: '100'});
phantom.exit();
});
于 2019-11-12T13:43:47.880 回答