iText7如何将HTML转换为PDF "System.NullReferenceException."

8
原标题: iTextSharp将HTML转换为PDF "The document has no pages."

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

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

The document has no pages.

这是我的当前代码:

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;
}

更新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();
      }
}

但是当我调用HtmlConverter.ConvertToDocument(html, pdfWriter)时,我遇到了

System.NullReferenceException

我错过了什么吗?


更新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

这是生成异常的代码:

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

更新3

问题与某种缓存相关,我无法确定是什么缓存,但是根据代码可以看出异常是在尝试从缓存中加载字体时生成的。
在一个新项目上尝试相同的代码后,我意识到这一点。

所以我清理了解决方案,删除了 bin、obj、.vs 文件夹,终止了 IIS Express,卸载并重新安装了所有 NuGet 包,然后再次运行,奇迹般地它工作了。

然后我只需要对代码进行一处修复:
我使用 HtmlConverter.ConvertToPdf 代替 HtmlConverter.ConvertToDocument 来生成完整的 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();
        }
    }
}

你有没有看过Stack Overflow上的这个问题和答案:使用iText将HTML转换为PDF? 两年前,我们发布了iText 7来取代iText 5,并将“iTextSharp”的名称更改为“iText for .NET”。你应该放弃你的代码并从iText 7 for .NETpdfHTML add-on重新开始。不要期望在旧的iText 5和XML Worker上获得太多帮助。 - Bruno Lowagie
1
请包含堆栈跟踪。 - mkl
可能是因为你的.NET Core版本?iText支持.NET Standard 1.6,即.NET Core 1.0 - kuujinbo
3个回答

13

我曾经遇到了完全相同的问题,一直深入到iText7的FontCache对象,并在尝试从原始TTF文件创建自己的FontProgram时收到错误(也出现了相同的空引用错误)。最终,我“解决”了我的问题。

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

Settings in Visual Studio

所以我花了四个小时来排除一个在他们代码中的问题,但他们似乎找到了某种方法来解决并推进该方法,即使在空引用失败的情况下。

我的转换为PDF函数现在完全正常工作。


1
这是正确的解决方法。我在8个月前开发了控制台应用程序,突然停止工作并在读取PDF时抛出类似的异常。但奇怪的是,这种方法可以解决问题 - 我想知道在VS中的某些设置如何影响使用iTextCore开发的代码!感谢这个解决方法,否则我可能会花几个小时来寻找解决方法,甚至可能切换到另一个付费的PDF阅读器库 :) - sanpat
1
谢谢!这对我有用,使用的是ItexSharp 5.5.13.3版本! - Diego Montania

0

我在控制台应用程序中使用itext 7一切正常。 当我在Web/Function App项目中使用相同的代码时,我开始收到以下错误。

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=itext.html2pdf
  StackTrace:
   at iText.Html2pdf.Attach.Impl.Tags.BrTagWorker..ctor(IElementNode element, ProcessorContext context)
   at iText.Html2pdf.Attach.Impl.DefaultTagWorkerMapping.<>c.<.cctor>b__1_10(IElementNode lhs, ProcessorContext rhs)
   at iText.Html2pdf.Attach.Impl.DefaultHtmlProcessor.Visit(INode node)
   at iText.Html2pdf.Attach.Impl.DefaultHtmlProcessor.Visit(INode node)
   at iText.Html2pdf.Attach.Impl.DefaultHtmlProcessor.Visit(INode node)
   at iText.Html2pdf.Attach.Impl.DefaultHtmlProcessor.Visit(INode node)
   at iText.Html2pdf.Attach.Impl.DefaultHtmlProcessor.Visit(INode node)
   at iText.Html2pdf.Attach.Impl.DefaultHtmlProcessor.Visit(INode node)
   at iText.Html2pdf.Attach.Impl.DefaultHtmlProcessor.Visit(INode node)
   at iText.Html2pdf.Attach.Impl.DefaultHtmlProcessor.ProcessDocument(INode root, PdfDocument pdfDocument)
   at iText.Html2pdf.HtmlConverter.ConvertToPdf(String html, PdfDocument pdfDocument, ConverterProperties converterProperties)
   at iTextSample.ConsoleApp.HtmlToPdfBuilder.RenderPdf() in C:\code\iTextSample.ConsoleApp\HtmlToPdfBuilder.cs:line 227

经过一番调查发现问题出在<br />标签上。我删除了所有的<br />标签,现在它可以正常工作了。

0

我也遇到了这个错误,但是注意到它只出现在第一次尝试加载SvgConverter时。所以我在我的类顶部添加了这个代码,并且似乎已经隐藏了这个错误。

using iText.Kernel.Pdf;
using iText.IO.Font;
public class PdfBuilder {

    static PdfBuilder() {
        try {
            FontCache.GetRegistryNames();
        }
        catch(Exception) {
            // ignored... this forces the FontCache to initialize
        }
    }
    ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接