how to pass html as a string using wkhtmltopdf?

后端 未结 3 1909
轻奢々
轻奢々 2020-12-04 10:29

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

相关标签:
3条回答
  • 2020-12-04 11:06

    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.

    0 讨论(0)
  • 2020-12-04 11:07

    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);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-04 11:10

    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.

    0 讨论(0)
提交回复
热议问题