Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iText7 convert HTML to PDF "System.NullReferenceException."

Tags:

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();
        }
    }
}
like image 581
Stefano Balzarotti Avatar asked Jul 24 '18 16:07

Stefano Balzarotti


1 Answers

I had this EXACT same problem, and after digging down all the way to iText7's FontCache object and getting an error when trying to create my OWN FontProgram to use from a raw TTF file (which also failed with the same null reference error), I finally "solved" my problem.

Apparently iText has some internal errors/exceptions that they are just sort of "skipping" and "pushing past", because I realized by accident that I had "Enable Just My Code" in Visual Studios disabled, and so my system was trying to debug iText7's code as well as mine. The moment that I re-enabled it in my Visual Studio settings (Tools > Options > Debugging > General > Enable Just My Code checkbox), the problem magically went away.

Settings in Visual Studio

So I spent four hours trying to troubleshoot a problem that was in THEIR code, but that they apparently found some way to work around and push through the method anyways even on a null reference failure.

My convert to PDF function is now working just fine.

like image 117
Westley Bennett Avatar answered Sep 28 '22 17:09

Westley Bennett