The free (MIT License) library PDFSharp can generate PDFs programmatically using C#.
It cannot (itself) convert HTML to PDFs, but some 3rd party solutions exist for that purpose
It can also handle some CSS (but it requires a specific syntax – ie. not all valid CSS is usable here)
Another option is Essential Objects PDF which contains an inbuilt HTML->PDF converter. This is NOT free, but an evaluation version is available.
It works very well, but contains an entire HTML engine, and hence, consumes quite a lot of memory. So much in fact, that you have to put a limit to the amount of simultaneous executions if you use it in an integration-scenario
On the positive side, it generates PDFs which looks very nice
Main page: https://github.com/ArthurHub/HTML-Renderer
SO: https://stackoverflow.com/questions/40431583/convert-html-to-pdf-using-htmlrenderer
Code needed to use EssentialObjects in a parallel (integration-style) scenario
private const int MAX_CONCURR_EOPDF_GENERATES = 10;
private const int MAX_WAIT_ON_EOPDF_MS = 120 * 1000;
// The essentialobjects PDF component will only allow 25 (by default) simultaneous PDF-generations. Ensure, that that number is not exceeded
string pdfFilename = io.Path.GetTempFileName();
TimeSpan waitedInSemaphore = TimeSpan.Zero;
bool semaphoreAcquired = false;
try {
timer.Restart();
if (_semaphore.WaitOne(MAX_WAIT_ON_EOPDF_MS)) { // Semaphore acquired
semaphoreAcquired = true;
waitedInSemaphore = timer.Elapsed;
timer.Restart();
CreatePdfFromHtml_EO(htmlFileInfo, pdfFilename, timer);
} else { // Wait timed out – Semaphore NOT acquired
waitedInSemaphore = timer.Elapsed;
throw new ApplicationException(string.Format(“Generation of PDF file failed. Timeout occurred after {0} sec. while waiting to access the PDF component.”, waitedInSemaphore.TotalSeconds));
}
} finally {
if (semaphoreAcquired)
_semaphore.Release();
}