10 ms·
QuestPDF: Modern .NET library for PDF document generation
- majkinetor 4y agoI am using this in prodution instead of Dink2PDF since recently, generating 30K PDF daily (in tens of minutes, with multiple threads). It works great, highly recommended. Dink2PDF was crashing monthly in this scenario due to internal unmanaged memory problem so we had to replace it. Not to mention, HTML to PDF libraries are insecure, and dink is no exception - you can execute arbitrary code on the server. Not to mention that you need to have full browser engine in your app...
- yyyk 4y agoCrashing is a problem with wrappers for wkhtmltopdf library when they run concurrently (you need the right locks, some wrappers have this but not dink apparently?). However, process-based wkhtmltopdf wrappers are also available and don't have this problem at all (e.g. nreco. It's also not too difficult to create a wrapper for oneself).
- majkinetor 4y agoWe had very funky case - the crash happened couple of times per month only, with web app doing daily work via REST API producing very large collection of pdfs on single API request, each having from couple to 5k pages. It was very hard to troublehsoot and pinpoint memory corruption problem (took us several months, one doesn't expect this in C# app). Finally we switched to QuestPDF. Surprisingly, performance was exactly the same as with dink (which is surprising); I see in recent changelog 50% speed up on textual PDFs so this might be a game changer (TBH performance is great even now). BTW, we used dink for half decade in public web apps with millions of users. Dink was used to create PDF reports and we never had a crash in that concurent scenario. However, when we started doing typical non-web multithreading this started to happen.
- isralcduke 4y agoDoes it help create tagged PDFs? Tagged PDFs are necessary to be accessible
- BaRRaKID 4y agoAre people really OK with writing code in C# for data presentation? How is it fine having to compile code when you want to change a font colour for example? And just from looking at the examples you can see how quickly it becomes messy. It looks like something that would work fine for very simple document structures but would get messy really fast once you add any level of complexity. Imagine having to write code for a document with multiple levels of headings, tables and images with captions, parts of text that need emphasis, etc. From my experience the best solution for generating PDFs in .NET are, as mentioned here before, wkhtmltopdf wrappers. Take a Razor view, add some document properties (page size, margins, headers, footers, etc) in code, and output to a PDF. I would even argue that on desktop using Office APIs to populate word documents and output them to PDF is more efficient than this.
- MarcinZiabek 4y agoThe concept of writing the presentation layer in the actual programming language isn't new. Flutter developed by Google is a great example. It all depends on how you structure your code. Of course, you can create huge chunks of HTML+CSS that cover your entire document. Or, to improve maintainability, you can split that HTML into multiple components and compose them together. Very similar rules can be applied to this library, where you split your code into smaller parts by using properly named methods. That gives you better understandding on the structure and ways to traverse the implementation. Futhermore, using a programming language gives you many benefits. You can rely on all language features like loops, conditions, methods, formatting, recursion, etc. You have access to IntelliSense, static analysis and refectoring tools. In terms of changing the layout content - it would be equally difficult when using any markup language. After all, you don't want to parse markup file every time you generate PDF - for performance reasons. HTML may be a good choice for relatively simple documents, where you don't care that much about splitting content between pages, etc. However, you still will fight with performance problems related to running entire web browser.
- Charlie_26 4y agoI’m planning on using Forms9Patch to get this working for a Xamarin project.
- hacknewslogin 4y agoVery cool, I'm looking to learn HTML, CSS, C and someday forth. Does anyone know if there's anything like this for those languages?
- cinntaile 4y agoI think you're in the wrong thread?
- hacknewslogin 4y agoThis is for making PDFs using C# code, right? And you can preview it while you work? I was wondering if that is available for other programming languages.
- xupybd 4y agohttps://en.m.wikipedia.org/wiki/JasperReports https://en.m.wikipedia.org/wiki/JasperReports https://en.m.wikipedia.org/wiki/Crystal_Reports https://en.m.wikipedia.org/wiki/Crystal_Reports https://pypi.org/project/pdf-reports/ https://pypi.org/project/pdf-reports/
- hacknewslogin 4y agoThanks!
- KRAKRISMOTT 4y ago>and someday forth PostScript is eternal
- yodon 4y agoSee Poe's Law [0] [0]https://en.wikipedia.org/wiki/Poe%27s_law https://en.wikipedia.org/wiki/Poe%27s_law
- imafish 4y agoIs you Bot?
- space_ghost 4y agoOh man, .NET needed this. Did some PDF work for a .NET project last year and found the ecosystem to be somewhat light on PDF support. There's a few commercial options, but they're pricey.
- yyyk 4y agoThe various wkhtmltopdf wrappers (there are many for .NET) work, but note wkhtmltopdf itself (based on Qt 4/5) is abandoned and the general response for issues was always 'just hack the HTML until it sorta works'.
- pathartl 4y agoWe've been on iTextSharp 5 for a decade for this reason.
- ejb999 4y agoI've used this one with great success (and its free): https://github.com/tuespetre/TuesPechkin https://github.com/tuespetre/TuesPechkin its basically a wrapper for wkhtmltopdf but I develop an app that has probably generated a million +/- invoices/statements over the past 5 years with it, and its been rock solid for me. Was a bit of a bear to get it working the first time (not a ton of documentation that I could find at the time), but once working, was easy to add/change new documents/layouts. As it uses wkhtmltopdf under to covers, it is a HTML->PDF tool, but I prefer that, at least for my use case. Not sure there is a dotnet-core version, so that might be a problem for some.
- hbcondo714 4y agoI've been using Rotativa[1] for URL to PDF generation which is also a wrapper for wkhtmltopdf. They have a dotnet-core[2] version and also a SaaS[3] but it's worth mentioning that Azure PaaS supports wkhtmltopdf[4] so I just self-host. Looking at QuestPDF's API docs, it doesn't look like they support URL / HTML to PDF generation. I think this would be a great addition especially given the age and issues with Rotativa and TuesPechkin on their public repos. [1] https://github.com/webgio/Rotativa https://github.com/webgio/Rotativa [2] https://github.com/webgio/Rotativa.AspNetCore https://github.com/webgio/Rotativa.AspNetCore [3] https://rotativa.io/ https://rotativa.io/ [4] https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#unsupported-frameworks https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandb...
- gibsonf1 4y agoWe've been really happy with https://pdfbox.apache.org/ https://pdfbox.apache.org/ in production, although not .net of course.
- petilon 4y agoThe hard part of PDF generation is support for complex script (Arabic, Indian languages etc.), including embedding a font subset. On Windows this is usually accomplished using the Uniscribe library (which is not available on Linux). QuestPDF appears to be using HarfBuzz for this purpose. If that works well then this is a winner!
- xoac 4y agoHarfBuzz is the gold standard.
- aliswe 4y agoJust a random fact, Harf means "letter" in arabic
- deleted 4y ago[deleted]
- petilon 4y agoGold standard? Even though serious bugs are not fixed [1] because "the code is too fragile to touch at this point"? Looks like Android uses HarfBuzz, if so it can't be that bad. [1] https://github.com/harfbuzz/harfbuzz/issues/2814 https://github.com/harfbuzz/harfbuzz/issues/2814
- ripberge 4y agoDoes this allow you to use existing PDFs as "templates"? We do that a lot with PDFs. It allows end users to design in Adobe Acrobat and upload to our product. We can then inject dynamic data into placeholders at runtime. We do this for text and images.
- PYTHONDJANGO 4y agoWhat are you using to do that? Thanks!
- phonon 4y agoDo you mean Acroforms?
- nateb2022 4y agoNot currently; however, there's an open issue regarding this very topic: https://github.com/QuestPDF/QuestPDF/issues/283 https://github.com/QuestPDF/QuestPDF/issues/283
- phpdave11 4y agoIt shouldn't be too difficult to add support for this. I authored a Go library which adds support for importing PDFs into a new PDF generator (either gofpdf or gopdf). It is around 2,500 lines of code: https://github.com/phpdave11/gofpdi https://github.com/phpdave11/gofpdi
- ahmedatia 4y agoNot at the moment. We are currently using RadPdfProcessing [1] from Telerik ($) to do so. It is a processing library that allows creation, import and export of PDF documents from code. [1] https://docs.telerik.com/devtools/document-processing/libraries/radpdfprocessing/overview https://docs.telerik.com/devtools/document-processing/librar...
- Scarbutt 4y agoNot knowing anything about PDF generation (but will need to soon), what can these libraries do that you can't do with something like a puppeteer web service and create PDFs with HTML/CSS?
- px1999 4y agoScale/performance. The interface is also straightforward to use. Puppeteer or any nonembedded process is just unnecessary hassle/overhead in a lot of cases.
- bayesian_horse 4y agoIt's an overhead but not a big one, at least for web applications, especially if they run as containers anyway. And then it really scales like crazy. Yes, this pdf generator may be faster at what it does, but a headless browser with paged media polyfill can do a lot more than this and uses html+css which are widely used standards.
- px1999 4y agoSure, but as others have said, how do you get column headers appearing on each page, put metadata into your documents, make elements properly selectable etc etc "Just run it as a container" is a bit of an industry cop-out for making stuff unnecessarily complex.
- bayesian_horse 4y agoTHEAD is supposed to do that already. You can use hyperlinks. You can postprocess pdf files.
- bigtex 4y agoTables over multiple pages is a major problem. It just doesn’t work with the popular htmlpdf tool that everyone uses to power their tools. That is the use case I am interested in.
- 4y ago
- mrwizrd 4y agoThis looks great. I am glad to still see good work being done in this space. I had used https://gotenberg.dev/ https://gotenberg.dev/ on AWS in the past. Many of the options available at the time weren't usable in Azure outside of a VM due to needing to make use of GDI interfaces that were disabled for security reasons. Interested to see how it compares to that and the other options being floated at the time like Puppeteer*
- jiggawatts 4y agoContainers can use the full Windows Server base image, which includes the GDI+ libraries. I used this as a trick for making Crystal Reports work.
- mwcampbell 4y agoI don't see any support for tagged PDF output. That's important for accessibility, particularly for screen reader users.
- nateb2022 4y agoGood point! There's an open issue regarding that, and it seems to be due to the fact that under the hood, QuestPDF uses Skia which itself lacks support for tagged PDF's: https://github.com/QuestPDF/QuestPDF/issues/193 https://github.com/QuestPDF/QuestPDF/issues/193
- qwertox 4y agoThis could be a SkiaSharp limitation. This thread made me interested in Skia and I started looking around their site and did a quick search for "tagged PDF" on their Milestone Release Notes. If they understand the same thing with tagged PDF as what is being discussed in this thread, that page says that "Add new APIs to add attributes to document structure node when creating a tagged PDF.", which could be a milestone as old as of 2020 [0] [0] https://skia.org/docs/user/release/release_notes/#milestone-82 https://skia.org/docs/user/release/release_notes/#milestone-...
- edragoev 4y agoThe .NET version of PDFjet supports tagged PDFs: https://github.com/edragoev1/pdfjet https://github.com/edragoev1/pdfjet so do the Java, Swift and Go versions. While the docs are somewhat sparse, Example_45 shows how to create PDF/UA compliant PDF.
- wackget 4y ago>> You are 250 lines of C# code away from creating a fully functional PDF invoice implementation. As a web developer this hurt to read. This is a task which is just crying out for a markup language and a stylesheet, not hundreds of lines of declarative C# code. Even the "complex example" in their documentation looks like the most basic of web pages.
- MarcinZiabek 4y agoThere are many good reasons of choosing the programming language over a markup language. C# has countless of features, both functional and syntactic: conditions, loops, methods, formatting, iteration, recursion, etc. Additionally, each of those features is well supported by all major IDEs. Writing your presentation layer in a proper programming language does not only rely on your existing skills but also gives you access to tools such us code completion and IntelliSense. Moreover, using FluentAPI helps with keeping the code concise and easy to change. At the end of the day, it all depends on how you use the technology, doesn't it?
- naasking 4y agoWill those basic web pages be less than 250 lines for the equivalent look? I'm skeptical.
- jaywalk 4y agoThere are PDF generators that work just like that. As a web developer who uses C# on the backend, QuestPDF is exactly what I want.
- pathartl 4y agoComing from the web dev space into backend on a project that heavily relies on PDF generation, I would say that something like a PDF often cannot be expressed with just markup and a stylesheet. There's a large difference in something like the web (it must be expressed with some fluidity of layout) compared to a very static document like a PDF. Page breaks, readability, print supply, watermarks, paging, etc all has to be considered.
- 4y ago
- yupis 4y agoSmart people of HN why can't I directly edit a PDF text file and change some letters?
- KMag 4y agoA PDF file is a program for a virtual machine that draws characters. For instance, I believe fonts in PDF work like PostScript fonts, where (for left-to-right languages) each glyph in the font is actually a bytecode function that starts with the brush in the lower-left corner of where the glyph is to be drawn, draws the glyph, and leaves the brush at the lower-left corner of where the next glyph is to be drawn. I think it's somewhat similar to turtle graphics, if you're familiar with Logo programming or G-code if you've ever hand-coded a CNC mill. (PostScript is text instead of bytecode. PDF is an odd mix of a binary and text format, which helps explain why it has had so many parsing security vulnerabilities over the years.) For common cases, it may be possible to basically decompile the PDF, modify the text, and re-flow the text, and re-compile to bytecode. However, it's very complicated to do in the general case. (Note that in HTML, the browser determines how to best layout the text, but with PDF, the PDF generator makes the layout decisions.) Also, many PDF renderers will "compress" fonts by lazily building up an embedded font as glyphs are used in the document. These typically will assign "a" to the first glyph used "b" to the second, etc., so if you decompile "This is some text", you'll see "abcd cd defg hgih". Some PDF generators will helpfully annotate the generated text with "backing text" metadata to help screen readers/copying-to-clipboard, but it's far from universal. So, you might need a database of hashes of all of the bytecode functions in a large number of fonts and/or some image-to-text software in order to reliably decompile the PDF. If you're unable to copy text out of a PDF or you get gibberish when you copy text from the PDF, it's likely because the PDF lacks this "backing text" metadata (and in the gibberish case, likely a compressed embedded font). Some scanners will helpfully perform OCR to add this backing text metadata to the generated PDF. Source: I did a small amount of work related to PDF analysis in Google's web search indexing pipeline over a decade ago. Most of my work was related to figuring out how JavaScript altered web page text, but I did learn just enough about PDF to be dangerous. At the time, Yahoo was Google's biggest competitor, and tons of their indexed PDFs had preview text that was this compressed font "abcd cd de..." garbage. Yahoo obviously naively decompiled the PDF and just trusted that "a" in the embedded font was a bytecode function that drew the glyph "a".
- lazyeye 4y agoWhy you would use anything other than a HTML -> PDF rendering engine is beyond me.
- password4321 4y agoIs there an open source pure-.NET library that implements this? I've heard good things about https://github.com/Kozea/WeasyPrint https://github.com/Kozea/WeasyPrint in Python.
- magnat 4y agoFor a proper page numbering, consistent word wrapping, pixel-perfect font rendering and document outline support.
- lazyeye 4y agoYou cant do page numbering in html? Seriously? I haven't had an issue with any of these things rendering html to pdf.
- trynewideas 4y agoThe Paged Media spec on counters and counter-resets paints implementations into a corner. They can't both comply with the spec and implement page count resets on page breaks. This has been a known issue with the spec since 2013[1][2] and been a thorn in implementations since.[3] 1: https://www.w3.org/Style/CSS/Tracker/issues/334 https://www.w3.org/Style/CSS/Tracker/issues/334 2: https://github.com/w3c/csswg-drafts/issues/4760 https://github.com/w3c/csswg-drafts/issues/4760 3: https://github.com/Kozea/WeasyPrint/issues/93#issuecomment-465932507 https://github.com/Kozea/WeasyPrint/issues/93#issuecomment-4...
- lazyeye 4y agoHere's some PHP code to handle page numbering (page breaks are no problem at all rendering html to pdf) :- <?php $pagenum = 1; $pagenum++; print("Page: $pagenum"); ?>
- mattferderer 4y agoThis looks awesome! The .NET foundation I hope supports this ASAP - https://old.dotnetfoundation.org/projects/ https://old.dotnetfoundation.org/projects/ I don't know if it's due to "partnerships" but I never could understand why Microsoft didn't do better at supporting .NET Word & PDF tooling since .NET Core came out. The older versions I know at least had support for Word docs. Creating documents is a huge foundation of their company.
- matchagaucho 4y agoThe Adobe vs Microsoft competitive relationship is indeed a puzzle. Some features, like eSignature, there's more co-opetition and partnering.
- bilekas 4y agoThe eSig is a key component. Need to be extended outside of AdoC.
- dustymcp 4y agoI think alot of people have moved on and are using services or puppeteer to generate their pdf's i know we did since we couldnt find a library that worked properly for our usecase.
- paranoidrobot 4y agothe tl;dr of using Puppeteer for this is "We run Chrome in a headless mode, load your page, and then print to PDF with it". It makes me nervous having Chrome running on the server, even inside a container without root. Doubly so if the user is able to control any portion of the page being run by Chrome.
- whitexn--g28h 4y agoWe used aws lambdas to execute the pdf renders and upload the result to s3 using a signed url passed in from the request. Complete insulation from our own application process, all of data is passed into the request so the worst the user can do is add a malicious file to our s3 bucket.
- xupybd 4y agoI still find jasper reports the best in pdf generation. Jasper studio gives you okay design tools. Much better than hand coding. Jasper server means integration is as simple as a rest interface. The community edition seems to do everything I need.
- msk-lywenn 4y agoWhat more this does that pdfsharp doesn’t ?
- marpstar 4y agoI see a Previewer utility of some sort: https://www.questpdf.com/document-previewer https://www.questpdf.com/document-previewer I've used PdfSharp in the past to generate product spec sheets in bulk. It worked fine. This one seems more focused on .NET 6 and modernity.
- renaudl_ 4y agoJust why aren’t you using an api like doppio.sh ?
- paranoidrobot 4y agoBecause it's an external paid service. Some people don't want, or can't use, external services like this. Security, Privacy, availability, cost... plenty of reasons. A library works offline, too.
- BlueNorth 4y agoWe must, one day, realize that .NET will disappear when Microsoft stops supporting it. All work done with this framework is only a prison for future developers. This must end.
- atraac 4y agoFirst of all, what does it have to do with this particular library? Second, get a grip, .NET is open source for a while, it's getting more popular again, JetBrains entered the stage with a very competetive IDE, it's easier than ever to use .NET via CLI, days of having to use Visual Studio, or any Microsoft product really, are long gone. I don't like Microsoft either but noone's forcing you to use any of their products anymore.
- aargh_aargh 4y agoHow would I go about using this from PowerShell?
- majkinetor 4y agoYou can even compile C# code in it, so it could be direct copy paste with some boilerplate.
- juki 4y agoYou could just build the example in C#, grab all the required dlls from it and then load them in PowerShell with `Add-Type -Path '.\QuestPDF.dll'`. Unfortunately it looks like this uses extension methods for everything, and those are a pain to use in PowerShell. You'll probably want to write the PDF creation bits as a C# cmdlet instead.