TuesPechkin
TuesPechkin copied to clipboard
TuePechkin crashes for sufficiently large pdf (6+ pages)
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);
}
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.
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.
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.
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?