toddams / RazorLight

Template engine based on Microsoft's Razor parsing engine for .NET Core
Apache License 2.0
1.51k stars 259 forks source link

RazorLite output to PDF #263

Closed TheColonel2688 closed 4 years ago

TheColonel2688 commented 5 years ago

I've used RazorLite for emails before, but now I have a new requirement which is to generate PDFs. Is there anyway I can convert the RazorLite to PDF without having to save it to disk first and then run it through a PDF converter library. I would like to do this all in memory including handling images in the HTML, and converting it to PDF.

ElleryW commented 5 years ago

I had the same question and ended up using this: https://github.com/rdvojmoc/DinkToPdf

It was very straightforward once I got started and now it works just fine. It does use some local disk space and that is configurable.

leandro-almeida commented 5 years ago

I had the same question and ended up using this: https://github.com/rdvojmoc/DinkToPdf

It was very straightforward once I got started and now it works just fine. It does use some local disk space and that is configurable.

Yeah, i also use DinkToPdf. I've implemented like this. You can get the string result from RazorLight: var html = await _razorLightEngine.CompileRenderAsync(cshtmlPath, viewModel);

Then you pass it to DinkToPdf to render:

 var doc = new HtmlToPdfDocument()
            {
                GlobalSettings = config,
                Objects = {
                    new ObjectSettings()
                    {
                        HtmlContent = html,
                        WebSettings = { DefaultEncoding = "utf-8", EnableJavascript = false }
                    }
                }
            };

            return _pdfConverter.Convert(doc);
nickalbrecht commented 4 years ago

I did the same, though it's been recommended to me to look into alternatives like using headless chrome. https://github.com/kblok/puppeteer-sharp which I have not yet done. Still using DinkToPDF currently.

toddams commented 4 years ago

I'd personally stick to "do one job" concept. Use RazorLight to build HTMLs and then pass it to some converter to create a PDF. It's a single facade thing

jzabroski commented 4 years ago

@nickalbrecht @TheColonel2688 One trick I've used, which I think is quite ingenius and not many people have given me credit for: https://stackoverflow.com/a/20155287/1040437

The idea is to create a web service that prints an arbitrary html page or page snippet as a pdf. It's truly a micro service*. As far as PDF libraries go, I've had great success with Aspose. Not plugging them, just being brutally honest working on many projects over the years, Aspose is bar none the best across ANY vendor in ANY language I've used. Had real scaling problems with PrinceXML in Ruby on Rails project, which exposed PrinceXML as too-clever-by-half.

In my "bag of knowledge", I can tell you wkhtmltopdf is a "false prophet" the last time I tried using it. In particular, since it is a wrapper around low-level C APIs and uses unsafe modules, it had to run in a 32 bit process space. This was back in 2012 so maybe things have changed and gotten better. But Aspose is worth the money to not deal with separate App Pool configurations JUST TO PRINT PDFs.

ALways simplify and ask why.

nickalbrecht commented 4 years ago

I've thought of doing the same, making a dedicated service that accepts HTML and spits out a PDF (server side, not client side). Haven't followed through with the idea yet as what I've got setup so far is working. It'd be easy enough to restrict access to it to certain IP's or to have it available in an intranet only and not publicly accessible to the internet. But for me the time investment to go from a working solution to a working solution is hard to pitch when the benefits are not immediately tangible.

But no matter what, converting from HTML (whether generated by RazorLight or not) to a PDF still requires that you render the document from HTML source, which is literally what a browser's primary purpose is. Regardless if you're rendering it to a screen, or to a PDF document. So if that's the only feature you need, something like Aspose is a bit overkill and pricey in my opinion.