Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wkhtmltopdf outputstream & download - diaglog

is it possible to get a pdf stream created by wkhtmltopdf from any html file and popup a download dialog in IE/Firefox/Chrome etc.?

At the moment I get my outputstream by this code:

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

Then I want to display the dialog:

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();

With MemoryStreams created from a PDF file this works fine, but here I only get an empty page. The bytearray has 1270 Bytes.

like image 739
Flg Avatar asked Apr 24 '12 06:04

Flg


People also ask

What is Wkhtmltopdf package?

wkhtmltopdf is an open source (LGPLv3) command line tool to render HTML into PDF using the Qt WebKit rendering engine.

What browser does Wkhtmltopdf use?

Historically, wkhtmltopdf was an excellent open-source HTML-to-PDF tool. It is one of the few open-source projects built solely for HTML-to-PDF generation and uses a specifically modified version of the WebKit browser engine.

How do I download Wkhtmltopdf?

Windows. Download the latest version of the package from the Wkhtmltopdf project releases page. Uncompress the downloaded archive and add the wkhtmltox\bin directory to your system path. Restart all running servers.

How do I use Wkhtmltopdf command line?

Open a command prompt window. The syntax for using the tool is fairly simple, enter the name wkhtmltopdf, followed by the URL of the web page, and the name of the PDF that you want to create, like so. Let's say you want to save a copy of a website, this is what the command will look like.


1 Answers

Is this still a problem?

I just created a new ASP.net website to test this on my computer after installing wkhtmltopdf 0.11.0 rc2 and it worked fine creating the PDF. My version was only slightly different;

In my CSHTML I had:

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();

My Derp class

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);
        }
    }
}
like image 126
Joel Peltonen Avatar answered Sep 27 '22 16:09

Joel Peltonen