代码之家  ›  专栏  ›  技术社区  ›  Stefano Balzarotti

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

  •  0
  • Stefano Balzarotti  · 技术社区  · 7 年前

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

    我正在使用iTextSharp和xmlworker在ASP中将html从视图转换为PDF。净核心2.1

    我尝试了许多在网上找到的代码片段,但都产生了一个例外:“文档没有页面。”

    以下是我目前的代码:

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

    但我了解这个系统。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
    

    这是生成异常的代码:

    static FontCache() {
                try {
                    LoadRegistry();
                    foreach (String font in registryNames.Get(FONTS_PROP)) {
                        allCidFonts.Put(font, ReadFontProperties(font));
                    }
                }
                catch (Exception) {
                }
    

    registryNames count=0和。Get(字体)抛出异常

    更新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();
            }
        }
    }
    
    0 回复  |  直到 7 年前
        1
  •  6
  •   Westley Bennett    5 年前

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

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

    Settings in Visual Studio

    所以我花了四个小时试图解决他们代码中的一个问题,但他们显然找到了一些方法来解决这个问题,甚至在出现空引用故障的情况下也能通过这个方法。

    我的转换为PDF功能现在运行良好。

        2
  •  0
  •   Alan Draper    4 年前

    我也遇到了这个错误,但注意到它只是在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
            }
        }
        ...
    }