pruiz / WkHtmlToXSharp

C# wrapper wrapper (using P/Invoke) for the excelent Html to PDF conversion library wkhtmltopdf library.
239 stars 84 forks source link

Converting HTML string to PDF - output is unformatted #18

Closed yellowbrickcode closed 8 years ago

yellowbrickcode commented 11 years ago

When I pass a Page from the Internet, it works perfectly and converts the HTML exactly as the page looks. My requirements however mean I need to pass it a string of HTML so I'm using Convert(ValidHtmlString) instead of setting a Page and just calling Convert().

When I pass in my HTML string, it's outputting a PDF, but it's completely unformatted. It even outputs my CSS style declarations. For example, here's the beginning of one of my PDF outputs:

body { font-family: Arial; font-size: 14px; width: 796px; } #letterLeft { width: 45%; padding-left: 7%; float: left; } #letterRight { width: 34%; float: left; padding-top: 20px; padding-left: 8%; } .GreenBox { margin-top: -8px; background-color: #D7E4BD; padding: 20px; width: 65%; border-radius: 10px; } .GreenBoxWide { margin-top: -8px; background-color: #D7E4BD; padding: 20px; width: 82%; borderradius: 10px; } .title { font-size: 1.2em; font-weight: bold; } .normal { font-size: 12px; font-weight: normal; } .subtext { font-size: 0.8em; } .icon { float: left; padding-right: 15px; } .floatRight { float: right; } Working in partnership with

Does anyone have any idea why this may be happening? Have I missed a setting somewhere? Here is my code for the converter:

public class ConvertToPDF { private bool ConvertComplete { get; set; }

    public byte[] HtmlToPdf(string html)
    {
        using (var toPdf = GetConverter())
        {
            toPdf.GlobalSettings.Margin.Top = "1cm";
            toPdf.GlobalSettings.Margin.Bottom = "1cm";
            toPdf.GlobalSettings.Margin.Left = "1cm";
            toPdf.GlobalSettings.Margin.Right = "1cm";

            toPdf.ObjectSettings.Web.EnablePlugins = false;
            toPdf.ObjectSettings.Web.EnableJavascript = false;
            toPdf.ObjectSettings.Load.Proxy = "none";

            byte[] pdfBytes = toPdf.Convert(html);

            if (pdfBytes != null && ConvertComplete)
            {
                return pdfBytes;
            }
            else
            {
                return null;
            }
        }
    }

    private MultiplexingConverter GetConverter()
    {
        var obj = new MultiplexingConverter();
        obj.Finished += new EventHandler<EventArgs<bool>>(obj_Finished);

        return obj;
    }

    void obj_Finished(object sender, EventArgs<bool> e)
    {
        ConvertComplete = true;
    }   
}

Thanks in advance.

yellowbrickcode commented 11 years ago

Ok, I finally figured it.

What I'm writing will eventually be called from a Windows Service that will have a message passed to it from a website. BUT!!! At the moment, I've written a test website to create the document for me to test various other parts of my code.

I'd never seen it convert it correctly, and therefore assumed it was a problem with my code. When I closed my Visual Studio and reopened it, it worked like magic. Obviously not magic, it's obviously to do with the same reasons you say not to use it directly from a website.

Anyway, it's working perfectly now. Hope this helps someone else!

pruiz commented 11 years ago

Glad you fixed it ;)

Sent from my iPhone

On 24/04/2013, at 17:28, Sarah notifications@github.com wrote:

Ok, I finally figured it.

What I'm writing will eventually be called from a Windows Service that will have a message passed to it from a website. BUT!!! At the moment, I've written a test website to create the document for me to test various other parts of my code.

I'd never seen it convert it correctly, and therefore assumed it was a problem with my code. When I closed my Visual Studio and reopened it, it worked like magic. Obviously not magic, it's obviously to do with the same reasons you say not to use it directly from a website.

Anyway, it's working perfectly now. Hope this helps someone else!

— Reply to this email directly or view it on GitHubhttps://github.com/pruiz/WkHtmlToXSharp/issues/18#issuecomment-16939078 .

yellowbrickcode commented 11 years ago

Just to clarify further on my above comment, I don't close and reopen Visual Studio everytime I want to test. I simply stop the virtual server that Visual Studio creates, forcing it to create a new one everytime I run my test website and this then works every time.

I'm glad I fixed it too, although it was one of those annoying problems that you spend hours trying to fix, only to find you should have tried the old faithful "turn it off and back on again" approach first! :+1:

dambrisco commented 11 years ago

Something worth noting: if at all possible you should separate out your wkhtmltox code into a WCF console app. Besides the issue you've run into, there is a serious bug in libwkhtmltox that is the result of a bug deep in QtWebkit which can cause a SIGABRT to fatally crash any application it bubbles up through - in this case your web application. The primary bug lies in handling child element widths of greater than 100% where the parent width is not set (in which case the end result is an attempt to draw an image which is 32,767 pixels wide), so properly sanitized HTML should be perfectly safe - if only sanitizing HTML styles were easy.

Of course, if what you've got is working for your purposes, feel free to ignore this. If you're pulling HTML off the internet from third parties, however, take caution.

pruiz commented 11 years ago

@dambrisco do you know if this bug is fixed on recent QTWebKit or wkhtmltopdf versions?

yellowbrickcode commented 11 years ago

Thanks @dambrisco. I'll make a note of this as a known issue in our system. At the moment it will be fine running from our Windows Service as we'll be writing the HTML templates ourselves for the foreseeable future so I will be sure we all know to set the parent width!

dambrisco commented 11 years ago

@pruiz Unfortunately, I haven't been able to find any actual documentation besides my own on the issue. In all likelihood, the latest QtWebKit fixes the issue, but I have no idea when we'll see a stable release of libwkhtmltox that incorporates it.

pruiz commented 8 years ago

Current release uses a more modern wkhtmltopdf native version, so I am closing this issue.