如何使用 wkhtmltopdf 将 html 作为字符串传递?

发布于 2024-10-11 04:25:25 字数 61 浏览 2 评论 0原文

如何使用 asp.net、c# 将 html 作为字符串而不是 wkhtmltopdf 中的 url 传递?

how to pass html as a string instead of url in wkhtmltopdf using asp.net, c#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

<逆流佳人身旁 2024-10-18 04:25:25

STDIn 和 STDOut 已在本示例中重定向,因此您根本不需要文件。

public static class Printer
{
    public const string HtmlToPdfExePath = "wkhtmltopdf.exe";

    public static bool GeneratePdf(string commandLocation, StreamReader html, Stream pdf, Size pageSize)
    {
        Process p;
        StreamWriter stdin;
        ProcessStartInfo psi = new ProcessStartInfo();

        psi.FileName = Path.Combine(commandLocation, HtmlToPdfExePath);
        psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName);

        // run the conversion utility
        psi.UseShellExecute = false;
        psi.CreateNoWindow = true;
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        // note: that we tell wkhtmltopdf to be quiet and not run scripts
        psi.Arguments = "-q -n --disable-smart-shrinking " + (pageSize.IsEmpty? "" : "--page-width " + pageSize.Width +  "mm --page-height " + pageSize.Height + "mm") + " - -";

        p = Process.Start(psi);

        try {
            stdin = p.StandardInput;
            stdin.AutoFlush = true;
            stdin.Write(html.ReadToEnd());
            stdin.Dispose();

            CopyStream(p.StandardOutput.BaseStream, pdf);
            p.StandardOutput.Close();
            pdf.Position = 0;

            p.WaitForExit(10000);

            return true;
        } catch {
            return false;

        } finally {
            p.Dispose();
        }
    }

    public static void CopyStream(Stream input, Stream output)
    {
        byte[] buffer = new byte[32768];
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0) {
            output.Write(buffer, 0, read);
        }
    }
}

STDIn and STDOut have been redirected in this example, so you shouldn't need files at all.

public static class Printer
{
    public const string HtmlToPdfExePath = "wkhtmltopdf.exe";

    public static bool GeneratePdf(string commandLocation, StreamReader html, Stream pdf, Size pageSize)
    {
        Process p;
        StreamWriter stdin;
        ProcessStartInfo psi = new ProcessStartInfo();

        psi.FileName = Path.Combine(commandLocation, HtmlToPdfExePath);
        psi.WorkingDirectory = Path.GetDirectoryName(psi.FileName);

        // run the conversion utility
        psi.UseShellExecute = false;
        psi.CreateNoWindow = true;
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        // note: that we tell wkhtmltopdf to be quiet and not run scripts
        psi.Arguments = "-q -n --disable-smart-shrinking " + (pageSize.IsEmpty? "" : "--page-width " + pageSize.Width +  "mm --page-height " + pageSize.Height + "mm") + " - -";

        p = Process.Start(psi);

        try {
            stdin = p.StandardInput;
            stdin.AutoFlush = true;
            stdin.Write(html.ReadToEnd());
            stdin.Dispose();

            CopyStream(p.StandardOutput.BaseStream, pdf);
            p.StandardOutput.Close();
            pdf.Position = 0;

            p.WaitForExit(10000);

            return true;
        } catch {
            return false;

        } finally {
            p.Dispose();
        }
    }

    public static void CopyStream(Stream input, Stream output)
    {
        byte[] buffer = new byte[32768];
        int read;
        while ((read = input.Read(buffer, 0, buffer.Length)) > 0) {
            output.Write(buffer, 0, read);
        }
    }
}
输什么也不输骨气 2024-10-18 04:25:25

重定向 STDIN 可能是完成您想要做的事情的最简单方法。

使用 wkhtmltopdf(在 ASP.Net 中)重定向 STDIN 的一种方法如下:

    private void WritePDF(string HTML)
    {
        string inFileName,
                outFileName,
                tempPath;
        Process p;
        System.IO.StreamWriter stdin;
        ProcessStartInfo psi = new ProcessStartInfo();

        tempPath = Request.PhysicalApplicationPath + "temp\\";
        inFileName = Session.SessionID + ".htm";
        outFileName = Session.SessionID + ".pdf";

        // run the conversion utility
        psi.UseShellExecute = false;
        psi.FileName = "c:\\Program Files (x86)\\wkhtmltopdf\\wkhtmltopdf.exe";
        psi.CreateNoWindow = true;
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        // note that we tell wkhtmltopdf to be quiet and not run scripts
        // NOTE: I couldn't figure out a way to get both stdin and stdout redirected so we have to write to a file and then clean up afterwards
        psi.Arguments = "-q -n - " + tempPath + outFileName;

        p = Process.Start(psi);

        try
        {
            stdin = p.StandardInput;
            stdin.AutoFlush = true;

            stdin.Write(HTML);
            stdin.Close();

            if (p.WaitForExit(15000))
            {
                // NOTE: the application hangs when we use WriteFile (due to the Delete below?); this works
                Response.BinaryWrite(System.IO.File.ReadAllBytes(tempPath + outFileName));
                //Response.WriteFile(tempPath + outFileName);
            }
        }
        finally
        {
            p.Close();
            p.Dispose();
        }

        // delete the pdf
        System.IO.File.Delete(tempPath + outFileName);
    }

请注意,上面的代码假定应用程序目录中有一个可用的 temp 目录。此外,您必须为运行 IIS 进程时使用的用户帐户显式启用对该目录的写访问权限。

Redirecting STDIN is probably the easiest way to accomplish what you're trying to do.

One method of redirecting STDIN with wkhtmltopdf (in ASP.Net) is as follows:

    private void WritePDF(string HTML)
    {
        string inFileName,
                outFileName,
                tempPath;
        Process p;
        System.IO.StreamWriter stdin;
        ProcessStartInfo psi = new ProcessStartInfo();

        tempPath = Request.PhysicalApplicationPath + "temp\\";
        inFileName = Session.SessionID + ".htm";
        outFileName = Session.SessionID + ".pdf";

        // run the conversion utility
        psi.UseShellExecute = false;
        psi.FileName = "c:\\Program Files (x86)\\wkhtmltopdf\\wkhtmltopdf.exe";
        psi.CreateNoWindow = true;
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;

        // note that we tell wkhtmltopdf to be quiet and not run scripts
        // NOTE: I couldn't figure out a way to get both stdin and stdout redirected so we have to write to a file and then clean up afterwards
        psi.Arguments = "-q -n - " + tempPath + outFileName;

        p = Process.Start(psi);

        try
        {
            stdin = p.StandardInput;
            stdin.AutoFlush = true;

            stdin.Write(HTML);
            stdin.Close();

            if (p.WaitForExit(15000))
            {
                // NOTE: the application hangs when we use WriteFile (due to the Delete below?); this works
                Response.BinaryWrite(System.IO.File.ReadAllBytes(tempPath + outFileName));
                //Response.WriteFile(tempPath + outFileName);
            }
        }
        finally
        {
            p.Close();
            p.Dispose();
        }

        // delete the pdf
        System.IO.File.Delete(tempPath + outFileName);
    }

Note that the code above assumes that there's a temp directory available in your application directory. Also, you must explicitly enable write access to that directory for the user account used when running the IIS process.

甜扑 2024-10-18 04:25:25

我知道这是一篇较旧的文章,但我希望未来的开发人员有这个选择。我有同样的需求,并且必须启动后台进程才能在网络应用程序中获取 PDF 的想法是可怕的。

这是另一个选项: https://github.com/TimothyKhouri/WkHtmlToXDotNet

它是 wkhtmltopdf 的 .NET 本机包装器。

示例代码在这里:

var pdfData = HtmlToXConverter.ConvertToPdf("<h1>COOOL!</h1>");

注意,它现在不是线程安全的 - 我正在努力解决这个问题。所以只需使用监视器或其他东西或锁即可。

I know this is an older post, but I want future developers to have this option. I had the same need, and the idea of having to start a background process just to get a PDF inside of a web app is terrible.

Here's another option: https://github.com/TimothyKhouri/WkHtmlToXDotNet

It's a .NET native wrapper around wkhtmltopdf.

Sample code here:

var pdfData = HtmlToXConverter.ConvertToPdf("<h1>COOOL!</h1>");

Note, it's not thread-safe as of right now - I'm working on that. So just use a monitor or something or a lock.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文