2011-01-10 42 views
22

如何通過html作爲字符串而不是網址在wkhtmltopdf使用asp.net,c#?如何使用wkhtmltopdf將html作爲字符串傳遞?

+0

這可能是最簡單的重定向stdin並傳遞字符串的方式。您也可以將文本寫入文件(儘管這當然不會很好)。 – 2011-01-10 20:49:49

+0

你能舉個例子嗎? – Eugene 2011-01-10 20:50:43

回答

16

重定向STDIN可能是完成您嘗試執行的最簡單的方法。 (在ASP.Net)與wkhtmltopdf重定向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); 
    } 

注意,上面的代碼假定有可用的臨時目錄中的應用程序目錄。此外,您必須顯式啓用對該目錄的寫入訪問權限,才能運行IIS進程時使用的用戶帳戶。

+0

我無法得到這與參考圖像和樣式表一起工作。那可能嗎?當我用磁盤上的文件運行命令行時,它可以工作。 – smerlung 2014-02-11 13:47:28

37

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); 
     } 
    } 
} 
3

我知道這是一個較舊的帖子,但我希望未來的開發者有這個選項。我也有同樣的需求,爲了在Web應用程序中獲取PDF而開始後臺進程的想法非常糟糕。

這裏的另一種選擇:https://github.com/TimothyKhouri/WkHtmlToXDotNet

這是圍繞wkhtmltopdf一個.NET本地包裝。

示例代碼瀏覽:

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

注意,它不是線程安全的,至於現在 - 我正在上。所以只需使用顯示器或其他東西或鎖。

相關問題