38

经过 10 个小时并尝试了 4 个其他 HTML 到 PDF 工具后,我准备好爆炸了。

wkhtmltopdf听起来像是一个很好的解决方案......问题是我无法从 asp.net 执行具有足够权限的进程,所以......

Process.Start("wkhtmltopdf.exe","http://www.google.com google.pdf");

开始但不做任何事情。

有没有简单的方法:

-a) 允许 asp.net 启动进程(实际上可以做某事)或
-b) 编译/包装/whatever wkhtmltopdf.exe 成我可以从 C# 使用的东西,如下所示:WkHtmlToPdf.Save("http://www.google.com", "google.pdf");

4

5 回答 5

25

你也可以使用佩奇金

.NET Wrapper for WkHtmlToPdf DLL,使用 Webkit 引擎将 HTML 页面转换为 PDF 的库。

Nuget 包:

佩奇金同步

佩奇金

于 2013-04-16T09:47:26.317 回答
23

我刚刚开始了一个新项目,以提供围绕 wkhtmltopdf 的 C# P/Invoke 包装器。

您可以在以下位置查看我的代码:https ://github.com/pruiz/WkHtmlToXSharp

问候。

于 2011-01-29T19:14:49.077 回答
18

感谢Paul,我找到了 Codaxy 编写的优秀包装器,也可以通过NuGet轻松下载。

经过几次试验,我已经管理了这个 MVC 操作,它可以立即创建 PDF 文件并将其作为流返回:

public ActionResult Pdf(string url, string filename)
{
    MemoryStream memory = new MemoryStream();
    PdfDocument document = new PdfDocument() { Url = url };
    PdfOutput output = new PdfOutput() { OutputStream = memory };

    PdfConvert.ConvertHtmlToPdf(document, output);
    memory.Position = 0;

    return File(memory, "application/pdf", Server.UrlEncode(filename));
}

在这里,Pdf* 类已在包装器中实现,具有漂亮、干净的代码,遗憾的是缺少文档。

在转换器中,URL 将被转换为 PDF,存储在临时文件中,复制到我们作为参数提供的流中,然后删除 PDF 文件。

最后,我们必须将流作为 FileStreamResult 推送。

不要忘记将输出流的位置设置为零,否则您将看到下载的 PDF 文件大小为零字节。

于 2012-09-11T23:45:23.513 回答
4

这是我使用的实际代码。请随时编辑它以消除一些气味和其他可怕的东西......我知道它不是那么好。

using System;
using System.Diagnostics;
using System.IO;
using System.Web;
using System.Web.UI;

public partial class utilities_getPDF : Page
{
    protected void Page_Load(Object sender, EventArgs e)
    {
        string fileName = WKHtmlToPdf(myURL);

        if (!string.IsNullOrEmpty(fileName))
        {
            string file = Server.MapPath("~\\utilities\\GeneratedPDFs\\" + fileName);
            if (File.Exists(file))
            {
                var openFile = File.OpenRead(file);
                // copy the stream (thanks to http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c)
                byte[] buffer = new byte[32768];
                while (true)
                {
                    int read = openFile.Read(buffer, 0, buffer.Length);
                    if (read <= 0)
                    {
                        break;
                    }
                    Response.OutputStream.Write(buffer, 0, read);
                }
                openFile.Close();
                openFile.Dispose();

                File.Delete(file);
            }
        }
    }

    public string WKHtmlToPdf(string Url)
    {
        var p = new Process();

        string switches = "";
        switches += "--print-media-type ";
        switches += "--margin-top 10mm --margin-bottom 10mm --margin-right 10mm --margin-left 10mm ";
        switches += "--page-size Letter ";
        // waits for a javascript redirect it there is one
        switches += "--redirect-delay 100";

        // Utils.GenerateGloballyUniuqueFileName takes the extension from
        // basically returns a filename and prepends a GUID to it (and checks for some other stuff too)
        string fileName = Utils.GenerateGloballyUniqueFileName("pdf.pdf");

        var startInfo = new ProcessStartInfo
                        {
                            FileName = Server.MapPath("~\\utilities\\PDF\\wkhtmltopdf.exe"),
                            Arguments = switches + " " + Url + " \"" +
                                        "../GeneratedPDFs/" + fileName
                                        + "\"",
                            UseShellExecute = false, // needs to be false in order to redirect output
                            RedirectStandardOutput = true,
                            RedirectStandardError = true,
                            RedirectStandardInput = true, // redirect all 3, as it should be all 3 or none
                            WorkingDirectory = Server.MapPath("~\\utilities\\PDF")
                        };
        p.StartInfo = startInfo;
        p.Start();

        // doesn't work correctly...
        // read the output here...
        // string output = p.StandardOutput.ReadToEnd();

        //  wait n milliseconds for exit (as after exit, it can't read the output)
        p.WaitForExit(60000);

        // read the exit code, close process
        int returnCode = p.ExitCode;
        p.Close();

        // if 0, it worked
        return (returnCode == 0) ? fileName : null;
    }
}
于 2010-05-14T13:41:37.403 回答
0

我无法发表评论,因此我将其发布为对上述答案的评论的“答案”如何在 ASP.net 中使用 wkhtmltopdf.exe

如果--redirect-delay不起作用,请尝试--javascript-delay 在此处查看所有选项:https ://github.com/antialize/wkhtmltopdf/blob/master/README_WKHTMLTOPDF

或者wkhtmltopdf -H寻求扩展帮助(afaik 与上述链接相同的输出)。

于 2011-03-23T00:23:17.350 回答