Search code examples
c#pdfresponsefile-conversion

HTML to PDF conversion - Almost works, but


I spent a good part of last few days searching for easy-to-use library that takes a html string as input, and produces PDF output as a file to the client browser.

Of the few dozen tools I tried out, a product called NReco PDF Generator, which is one of many derivative tools based on wkhtmltopdf, seems to suit my needs.

Here's my test code:

var strHtml = String.Format("<h1>Hello World!</h1>");

Response.Clear();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment; filename=test.pdf");

(new NReco.PdfGenerator.HtmlToPdfConverter()).GeneratePdf(strHtml, null, Response.OutputStream);
Response.End();

With the above code, I expected to see a PDF file being passed to my browser. Instead, I only see the output stream being generated in my developer console. (BTW, I'm using Chrome)

My question is NOT about how the said product works, which I think is working as intended, but it is about whether my code is missing any action for the .NET's Response object or is doing anything wrong. As I already indicated, I can see the converted Pdf stream in the console. I think it's just a matter of capturing that stream in a file and passing it to the client.


Solution

  • The missing line is Response.BinaryWrite(pdfBytes). Without that line the PDF will not be rendered to the user.

    As far as I can tell you do not need the lines:

    Response.Clear();
    Response.ClearHeaders();
    

    The following works for me (Obviously, you need to add using NReco.PdfGenerator;)

    string strHtml = String.Format("<h1>Hello World!</h1");
    HtmlToPdfConverter pdfConverter = new HtmlToPdfConverter();
    var pdfBytes = pdfConverter.GeneratePdf(strHtml);
    
    Response.ContentType = "application/pdf";
    Response.ContentEncoding = System.Text.Encoding.UTF8;
    Response.AddHeader("Content-Disposition", "Inline; filename=TEST.pdf");
    Response.BinaryWrite(pdfBytes);
    Response.Flush();
    Response.End();