Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to pass html as a string using wkhtmltopdf?

Tags:

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

like image 480
Eugene Avatar asked Jan 10 '11 20:01

Eugene


2 Answers

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);         }     } } 
like image 97
Daniel Little Avatar answered Sep 25 '22 04:09

Daniel Little


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.

like image 42
Michael Todd Avatar answered Sep 25 '22 04:09

Michael Todd