TuesPechkin icon indicating copy to clipboard operation
TuesPechkin copied to clipboard

TuePechkin crashes for sufficiently large pdf (6+ pages)

Open jdbaker opened this issue 10 years ago • 4 comments

I have a few reports I'm creating for a custom portal. I'm using tuespechkin with a static deployment and the latest version of wkhtmltopdf. I can convert the site manually using the command line tool, but it crashes when using tuespechkin.

I can convert web pages with less content without problems, but when the content scales up to 6 pages then everything hangs and I get a SEHException exception.

This is the stack trace: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Runtime.InteropServices.SEHException: External component has thrown an exception.

Server stack trace: at TuesPechkin.WkhtmltoxBindings.wkhtmltopdf_convert(IntPtr converter) at TuesPechkin.PdfToolset.PerformConversion(IntPtr converter) at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs) at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg)

Exception rethrown at [0]: at TuesPechkin.ThreadSafeConverter.Invoke[TResult](FuncShim`1 delegate) at TuesPechkin.ThreadSafeConverter.Convert(IDocument document)

I have this for my converter:

    public class ConverterSingleton 
    {

        private static IConverter converter;
        public static IConverter GetConverter()
        {
            if(ConverterSingleton.converter == null) 
            {
                ConverterSingleton.converter = 
                    new ThreadSafeConverter(
                        new RemotingToolset<PdfToolset>(
                            new StaticDeployment("C:\\Program Files (x86)\\wkhtmltopdf\\bin")));  
            }
            return ConverterSingleton.converter;
        }
    }

And this is my webservice I'm using to convert sites:

        [WebMethod]
        public string ConvertSiteToPdf(string Url, string Title)
        {
            //todo: put restrictions in place before deploying


            var document = new HtmlToPdfDocument
            {
                GlobalSettings =
                {
                    ProduceOutline = true,
                    DocumentTitle = Title,
                    PaperSize =  PaperKind.A4, // Implicit conversion to PechkinPaperSize
                    Margins =
                    {
                        All = 0.1,
                        Unit = Unit.Inches
                    }
                },
                Objects = {
                    new ObjectSettings { PageUrl = Url }
                }
            };
            var PdfObject = new { data = ConverterSingleton.GetConverter().Convert(document) };
            return Newtonsoft.Json.JsonConvert.SerializeObject(PdfObject);
        }

jdbaker avatar Jun 18 '15 21:06 jdbaker

Although it does not seem to be your issue here, I should point out that your singleton is not thread safe. private static IConverter converter = new .... with a public static getter is a better option, and it will be initialized on-demand.

I'll get back to you on the rest.

tuespetre avatar Jul 17 '15 02:07 tuespetre

I am using TuesPechkin converter for almost a year now and for pdfs of even +500 Pages. Nothing works better than this when it comes to dealing with large amounts of data - believe me, I've searched and tried.

And I am not making free advertisments - this really works. As DLLs I use: TuesPechkin TuesPechkin.Wkhtmltox.Win64

Here's my code sample:

public static class TuesPechkinInitializerService
    {
        private static string staticDeploymentPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wkhtmltopdf");

        public static void CreateWkhtmltopdfPath()
        {
            if (Directory.Exists(staticDeploymentPath) == false)
            {
                Directory.CreateDirectory(staticDeploymentPath);
            }
        }

        public static IConverter converter = 
            new ThreadSafeConverter(
                new RemotingToolset<PdfToolset>(
                    new Win64EmbeddedDeployment(
                        new StaticDeployment(staticDeploymentPath)
                    )
                )
            );
    }

So I placed this class simply somewhere in my project. I call the CreateWkhtmltopdfPath() in my Global.asax (you should place it in your application start or something like that but ONLY once it should be called)

And when I want to convert something, I do:

  GlobalSettings settings = new GlobalSettings
                {
                    Margins =
                    {
                        Top = 0.8,
                        Bottom = 0.8,
                        Left = 0.6,
                        Right = 0.6,
                        Unit = Unit.Centimeters
                    },
                    ImageDPI = 200,
                    ImageQuality = 400,
                    DPI = 200
                };
 HtmlToPdfDocument pdfDocument = new HtmlToPdfDocument
                {
                    GlobalSettings = settings,
                    Objects =
                    {
                        new ObjectSettings
                        { 
                            ProduceLocalLinks = true,
                            ProduceForms = true,
                            HtmlText = htmlContent
                        }                    
                    }
                };

                byte[] pdfDocumentData = TuesPechkinInitializerService.converter.Convert(pdfDocument);

... where htmlContent is a string. Hope that helps you.

alin-prisecaru avatar Jul 17 '15 07:07 alin-prisecaru

I should have mentioned above that I've been using bootstrap 2.2 in my css. While this should be css 2.0 only, and therefore compliant with the wkhtmltopdf webkit rendering engine, it looks like its not. Getting rid of bootstrap and hand-rolling my own css fixed the issue. Thanks for the advice on my singleton not being threadsafe.

jdbaker avatar Jul 17 '15 13:07 jdbaker

Hmmm... I use Bootstrap quite heavily myself, though I haven't tried it with wkhtmltopdf. I can't imagine CSS causing that kind of problem. Maybe it was something with the some javascript that related to having Bootstrap's js include on your page?

tuespetre avatar Jul 20 '15 13:07 tuespetre