iText7 将 HTML 转换为 PDF“System.NullReferenceException”。

Ste*_*tti 8 pdf itext xmlworker .net-core itext7

旧标题:iTextSharp 将 HTML 转换为 PDF“文档没有页面。”

我正在使用 iTextSharp 和 xmlworker 将 html 从视图转换为 ASP.NET Core 2.1 中的 PDF

我尝试了在网上找到的许多代码片段,但都生成了异常:

该文档没有页面。

这是我当前的代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

更新1

感谢 @Bruno Lowagie 的建议,我升级到了 iText7 和 pdfHTML,但我找不到太多关于它的教程。

我尝试了这段代码:

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();
      }
}
Run Code Online (Sandbox Code Playgroud)

但我得到

系统.NullReferenceException

当我打电话时HtmlConverter.ConvertToDocument(html, pdfWriter)

我错过了什么吗?


更新2

我尝试使用源代码进行调试。

这是堆栈跟踪

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
Run Code Online (Sandbox Code Playgroud)

这是生成异常的代码:

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
Run Code Online (Sandbox Code Playgroud)

更新3

该问题与某种缓存有关。我不太明白是什么,但正如您在代码中看到的那样,当它尝试从缓存加载字体时会生成异常。
在一个新项目上尝试了相同的代码并在其中运行后,我意识到了这一点。

所以我清理了解决方案,删除了 bin、obj、.vs,杀死了 IIS Express,删除并重新安装了所有 nuget 软件包,然后再次运行,神奇地它工作了。

然后我只需对代码进行一处修复:
而不是HtmlConverter.ConvertToDocument只生成一个 15 字节的文档,我用它HtmlConverter.ConvertToPdf来生成完整的 PDF。

这是完整的代码:

public static byte[] ToPdf(string html)
{
    using (var workStream = new MemoryStream())
    {
        using (var pdfWriter = new PdfWriter(workStream))
        {                    
            HtmlConverter.ConvertToPdf(html, pdfWriter);
            return workStream.ToArray();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Wes*_*ett 13

我遇到了这个完全相同的问题,在一直挖掘到 iText7 的 FontCache 对象并在尝试创建我自己的 FontProgram 以从原始 TTF 文件使用时收到错误(该文件也因相同的空引用错误而失败),我终于“解决”了我的问题。

显然 iText 有一些内部错误/异常,它们只是“跳过”和“推过去”,因为我偶然意识到我在 Visual Studios 中禁用了“仅启用我的代码”,所以我的系统正在尝试调试iText7 的代码和我的代码一样。当我在 Visual Studio 设置中重新启用它(“工具”>“选项”>“调试”>“常规”>“仅启用我的代码”复选框)时,问题就神奇地消失了。

Visual Studio 中的设置

因此,我花了四个小时尝试解决他们代码中的问题,但他们显然找到了某种方法来解决并推动该方法,即使在空引用失败的情况下也是如此。

我的转换为 PDF 功能现在工作得很好。