OLD TITLE: iTextSharp convert HTML to PDF "The document has no pages."
I am using iTextSharp and xmlworker to convert html from a view to PDF in ASP.NET Core 2.1
I tried many code snippets I found online but all generate an exception:
The document has no pages.
Here is my current code:
public static byte[] ToPdf(string html) { byte[] output; using (var document = new Document()) { using (var workStream = new MemoryStream()) { PdfWriter writer = PdfWriter.GetInstance(document, workStream); writer.CloseStream = false; document.Open(); using (var reader = new StringReader(html)) { XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader); document.Close(); output = workStream.ToArray(); } } } return output; } UPDATE 1
Thanks to @Bruno Lowagie's advice, I upgraded to iText7 and pdfHTML, but I can't find much tutorials about it.
I tried this code:
public static byte[] ToPdf(string html) { html = "<html><head><title>Extremely Basic Title</title></head><body>Extremely Basic Content</body></html>"; byte[] output; using (var workStream = new MemoryStream()) using (var pdfWriter = new PdfWriter(workStream)) { using (var document = HtmlConverter.ConvertToDocument(html, pdfWriter)) { //Passes the document to a delegated function to perform some content, margin or page size manipulation //pdfModifier(document); } //Returns the written-to MemoryStream containing the PDF. return workStream.ToArray(); } } but I get
System.NullReferenceException
when I call HtmlConverter.ConvertToDocument(html, pdfWriter)
Am I missing something?
UPDATE 2
I tried to debug using source code.
This is the stack trace
System.NullReferenceException HResult=0x80004003 Message=Object reference not set to an instance of an object. Source=itext.io StackTrace: at iText.IO.Font.FontCache..cctor() in S:\Progetti\*****\itext7-dotnet-develop\itext\itext.io\itext\io\font\FontCache.cs:line 76 This is the code that generates the exception:
static FontCache() { try { LoadRegistry(); foreach (String font in registryNames.Get(FONTS_PROP)) { allCidFonts.Put(font, ReadFontProperties(font)); } } catch (Exception) { } } registryNames count = 0 and .Get(FONTS_PROP) throws the exception UPDATE 3
The problem was related to some sort of cache. I can't really understand what, but as you can see in the code the exception was generated when it tried to load fonts from cache.
I realized that, after having tried the same code on a new project where it worked.
So I cleaned the solution, deleted bin, obj, .vs, killed IIS Express, removed and reinstalled all nuget packages then run again, magically it worked.
Then I had to make only one fix to the code:
Instead of HtmlConverter.ConvertToDocument that generates only a 15 bytes document I used HtmlConverter.ConvertToPdf to generate a full PDF.
Here is the complete code:
public static byte[] ToPdf(string html) { using (var workStream = new MemoryStream()) { using (var pdfWriter = new PdfWriter(workStream)) { HtmlConverter.ConvertToPdf(html, pdfWriter); return workStream.ToArray(); } } } 