【问题标题】:Generating PDFs using Phantom JS on .NET applications在 .NET 应用程序上使用 Phantom JS 生成 PDF
【发布时间】:2013-10-28 22:38:56
【问题描述】:

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

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

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

我是 .NET 世界的新手,希望能得到更详细的答案。感谢大家。 :)

【问题讨论】:

    标签: asp.net asp.net-mvc phantomjs


    【解决方案1】:

    我不知道最佳实践,但是,我正在使用 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 创建并由应用程序加载到请求。

    【讨论】:

    • 谢谢费利佩。这很棒。
    • 您可以使用 Process.WaitForExit 而不是 do while 循环。 msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx
    • 当应用程序在 Windows Server 2008+ 上的 IIS 中运行时,这不起作用。此解决方案在您从 Visual Studio 测试时有效,但在部署到 IIS 时无法在生产环境中工作,stackoverflow.com/a/5308011/1062224
    • 自我发布此答案之日起,我们就一直在使用它,它工作正常。
    • @Filepe Miosso 您使用的是什么版本的 Windows Server、IIS 和 .NET 框架?
    【解决方案2】:

    如果您愿意使用为 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();
        }
    }
    

    【讨论】:

    • 是的,并且需要商业许可证。
    • @Tom 取决于您的应用程序,根据他们的常见问题解答,它“可以在单一部署项目(网站、Intranet/Extranet)或用于公司内部业务目的的应用程序中免费使用(仅在内部重新分发)公司)。”
    【解决方案3】:

    以下是使用 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();
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-01
      • 2010-10-17
      • 2016-11-26
      • 2014-10-15
      • 1970-01-01
      • 2010-11-09
      • 2017-08-23
      相关资源
      最近更新 更多