2012-04-24 38 views
6

là có thể nhận được một luồng pdf được tạo bởi wkhtmltopdf từ bất kỳ tệp html nào và bật lên hộp thoại tải xuống trong IE/Firefox/Chrome, v.v ... không?wkhtmltopdf outputstream & download - diaglog

Tại thời điểm này tôi nhận được OutputStream của tôi bằng cách mã này:

public class Printer 
{ 
    public static MemoryStream GeneratePdf(StreamReader Html, MemoryStream pdf, Size pageSize) 
    { 
     Process p; 
     StreamWriter stdin; 
     ProcessStartInfo psi = new ProcessStartInfo(); 

     psi.FileName = @"C:\PROGRA~1\WKHTML~1\wkhtmltopdf.exe"; 

     // 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 pdf; 
     } 
     catch 
     { 
      return null; 
     } 
     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); 
     } 
    } 
} 

Sau đó, tôi muốn hiển thị hộp thoại:

MemoryStream PDF = Printer.GeneratePdf(Rd, PDFStream, Size); 

byte[] byteArray1 = PDF.ToArray(); 
PDF.Flush(); 
PDF.Close(); 
Response.BufferOutput = true; 

Response.Clear(); 
Response.ClearHeaders(); 
Response.AddHeader("Content-Disposition", "attachment; filename=Test.pdf"); 
Response.ContentType = "application/octet-stream"; 
Response.BinaryWrite(byteArray1); 
Response.End(); 

Với MemoryStreams được tạo ra từ một tập tin PDF này làm việc tốt, nhưng ở đây Tôi chỉ nhận được một trang trống. Bytearray có 1270 Byte.

+0

Bạn có khắc phục vấn đề này? Giải pháp của tôi có giúp được không? – Nenotlep

Trả lời

3

Đây có phải là sự cố không?

Tôi vừa tạo một trang web ASP.net mới để kiểm tra điều này trên máy tính của mình sau khi cài đặt wkhtmltopdf 0.11.0 rc2 và nó hoạt động tốt khi tạo tệp PDF. Phiên bản của tôi chỉ hơi khác một chút;

Trong CSHTML của tôi, tôi có:

MemoryStream PDFStream = new MemoryStream(); 
MemoryStream PDF = Derp.GeneratePdf(PDFStream); 
byte[] byteArray1 = PDF.ToArray(); 
PDF.Flush(); 
PDF.Close(); 
Response.BufferOutput = true; 
Response.Clear(); 
Response.ClearHeaders(); 
Response.AddHeader("Content-Disposition", "attachment; filename=Test.pdf"); 
Response.ContentType = "application/octet-stream"; 
Response.BinaryWrite(byteArray1); 
Response.End(); 

lớp derp My

public class Derp 
{ 
    public static MemoryStream GeneratePdf(MemoryStream pdf) 
    { 
     using (StreamReader Html = new StreamReader(@"Z:\HTMLPage.htm")) 
     { 
      Process p; 
      StreamWriter stdin; 
      ProcessStartInfo psi = new ProcessStartInfo(); 
      psi.FileName = @"C:\wkhtmltopdf\wkhtmltopdf.exe"; 
      psi.UseShellExecute = false; 
      psi.CreateNoWindow = true; 
      psi.RedirectStandardInput = true; 
      psi.RedirectStandardOutput = true; 
      psi.RedirectStandardError = true; 
      psi.Arguments = "-q -n --disable-smart-shrinking " + " - -"; 
      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 pdf; 
      } 
      catch 
      { 
       return null; 
      } 
      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

Vì vậy, nếu bạn có vấn đề với đầu ra, bạn có thể muốn kiểm tra làm thế nào bạn nhận được nguồn HTML để chuyển đổi nếu có bất kỳ vấn đề trong đó. – Nenotlep

+0

+ "- -" là gì; cho ở cuối các đối số của bạn? –

+1

@Mvision Tôi đã ghép nó một cách ngu ngốc, nhưng nó có nghĩa là thay vì các tệp cho đầu vào và đầu ra, tôi sẽ sử dụng các luồng như đầu vào và đầu ra. Ví dụ, để có được wkhtmltopdf để có được đầu vào của nó từ STDIN thay vì một tập tin hoặc URL và đầu ra cho một tập tin bạn muốn sử dụng 'wkhtmltopdf.exe - output.pdf'. Tương tự như vậy để sử dụng một tập tin đầu vào và đầu ra cho STDOUT (hoặc có thể stderr, không thể nhớ), bạn sẽ sử dụng 'wkhtmltopdf.exe input.html -' – Nenotlep