Tuesday 23 August 2011

Asp.Net: Generate PDF from Web Page

Question:
How to convert Html to PDF for a web page with wkhtmltopdf in asp.net ?
How to generate PDF from HTML using wkhtmltopdf in .net?


Answer:
Wkhtmltopdf is a simple command line utility to convert HTML to PDF using the webkit rendering engine.
With this utility you can either transform html or entire pages to pdf.
To use this inside asp.net you use the Process class, set some params and call the Start() method.

Wkhtmltopdf has many options. Here is a manual.

Here is an example
This code is updated from stackoverflow
private byte[] GeneratePdf(string pageUrl)
{
    Process p = new Process();
    // You can tell wkhtmltopdf to send it's output to sout by specifying "-" as the output file.
    string outFileName = "-";
    // get webUi physical path
    string baseDir = AppDomain.CurrentDomain.BaseDirectory;

    string exeFileName = System.IO.Path.Combine(baseDir, "bin\\wkhtmltopdf.exe");
    int waitTime = 30000;

    string switches = "";
    switches += "--print-media-type ";
    switches += "--page-size A4 ";
    // dots per inch
    switches += "--dpi 100 ";

    p.StartInfo.Arguments = switches + " " + pageUrl + " " + outFileName;

    p.StartInfo.UseShellExecute = false; // needs to be false in order to redirect output
    p.StartInfo.RedirectStandardOutput = true;
    p.StartInfo.RedirectStandardError = true;
    p.StartInfo.RedirectStandardInput = true;

    p.StartInfo.FileName = exeFileName;
    p.StartInfo.WorkingDirectory = exeFileName.Substring(0, exeFileName.LastIndexOf('\\'));

    p.Start();

    //read output
    byte[] buffer = new byte[32768];
    byte[] file;
    using (MemoryStream ms = new MemoryStream())
    {
        while (true)
        {
            int read = p.StandardOutput.BaseStream.Read(buffer, 0, buffer.Length);

            if (read <= 0)
            {
                break;
            }
            ms.Write(buffer, 0, read);
        }
        file = ms.ToArray();
    }

    // wait or exit
    p.WaitForExit(waitTime);

    // read the exit code, close process
    int returnCode = p.ExitCode;
    p.Close();

    return (returnCode == 0 || returnCode == 2) ? file : null;

}

No comments: