简体   繁体   English

iTextSharp在关闭文档时引发异常

[英]iTextSharp throws exception at closing document

I'm having problems with the following code in C# with Webforms in ASP.NET. 我在ASP.NET中使用Webforms的C#中的以下代码遇到问题。 I have spent quite a while looking for the answer, but no luck so far. 我花了很长时间寻找答案,但到目前为止还没有运气。

Document docPDF = new Document(PageSize.LETTER, this.LM, this.RM, this.TM, this.BM);
        this.writer = PdfWriter.GetInstance(docPDF, this.thePage.Response.OutputStream);

        docPDF.Open();

        for (int i = 0; i < elements.Count; i++)
        {
            docPDF.Add(elements[i]);
        }

        if (docPDF.IsOpen()) docPDF.Close();
        thePage.Response.HeaderEncoding = System.Text.Encoding.Default;
        thePage.Response.ContentType = "application/pdf; charset=utf-8";
        thePage.Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
        thePage.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        thePage.Response.Write(docPDF);
        thePage.Response.Flush();
        thePage.Response.End();

I'm getting a NullReferenceException at docPDF.Close(); 我在docPDF.Close()处收到NullReferenceException。

All the variables that use the "this" keyword have been initialized, while debugging they do display values. 使用“ this”关键字的所有变量都已初始化,而在调试时它们确实显示值。

I'm using the exact same code in other projects, the same library (DLL) but this time it's simply not working. 我在其他项目中使用了完全相同的代码,相同的库(DLL),但这一次它根本无法正常工作。 The elements array is a List< IElement> I fill with PdfPTable, Paragraph, Chunk and Image objects. elements数组是一个List <IElement>,我用PdfPTable,Paragraph,Chunk和Image对象填充。 When I debug it, they're there. 当我调试它时,它们在那里。

No error while opening the file I'm writing, no error when I add the elements, I check if the file is open and then try to close it, but then it simply won't close. 打开我正在写的文件时没有错误,添加元素时没有错误,我检查文件是否打开,然后尝试关闭它,但是它根本不会关闭。

If I comment out the line, no exception is thrown, but the file is saved with errors and won't open to be read. 如果我注释掉该行,则不会引发任何异常,但是该文件会保存有错误,并且不会打开以供读取。

Any ideas? 有任何想法吗?

UPDATE Here's the stack trace. 更新这是堆栈跟踪。 As you can see, it's line 246, and following the stack trace, it does says that it is the Close() method. 如您所见,它是第246行,并遵循堆栈跟踪,它确实说这是Close()方法。 As a matter of fact, I added the "if (docPDF.IsOpen())" part after it started crashing. 实际上,我开始崩溃后添加了“ if(docPDF.IsOpen())”部分。 Debugging it, it does reach the docPDF.Close(); 对其进行调试,的确到达了docPDF.Close();。

Line 244:        }
Line 245:        
Line 246:        if (docPDF.IsOpen()) docPDF.Close();
Line 247:        thePage.Response.HeaderEncoding = System.Text.Encoding.Default;
Line 248:        pagina.Response.ContentType = "application/pdf; charset=utf-8";

Source File: c:\Mao\Proyectos\Desarrollos\Avantare\PMTool\Codigo\App_Code\Comunicacion\Reportes\ExportadorPDF.cs    Line: 246 

Stack Trace: 


[NullReferenceException: Object reference not set to an instance of an object.]
   iTextSharp.text.pdf.CFFFontSubset.CreateNonCIDSubrs(Int32 Font, IndexBaseItem PrivateBase, OffsetItem Subrs) +135
   iTextSharp.text.pdf.CFFFontSubset.BuildNewFile(Int32 Font) +3389
   iTextSharp.text.pdf.CFFFontSubset.Process(String fontName) +275
   iTextSharp.text.pdf.TrueTypeFontUnicode.WriteFont(PdfWriter writer, PdfIndirectReference piref, Object[] parms) +1525
   iTextSharp.text.pdf.FontDetails.WriteFont(PdfWriter writer) +680
   iTextSharp.text.pdf.PdfWriter.AddSharedObjectsToBody() +244
   iTextSharp.text.pdf.PdfWriter.Close() +504
   iTextSharp.text.pdf.PdfDocument.Close() +291
   iTextSharp.text.Document.Close() +146
   ExportadorPDF.Exportar(String nombreArchivo) in c:\Mao\Proyectos\Desarrollos\Avantare\PMTool\Codigo\App_Code\Comunicacion\Reportes\ExportadorPDF.cs:246
   Reportes.Page_Load(Object sender, EventArgs e) in c:\Mao\Proyectos\Desarrollos\Avantare\PMTool\Codigo\Reportes.aspx.cs:32
   System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
   System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35
   System.Web.UI.Control.OnLoad(EventArgs e) +91
   System.Web.UI.Control.LoadRecursive() +74
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +2207

Another thing, perhaps this is worth mentioning to see any thoughts on the matter before I start changing the code, but as you can see in the stack, I'm calling the method that does this process from the Page_Load event. 另一件事,也许值得一提的是,在我开始更改代码之前,要对此事有任何想法,但是正如您在堆栈中所看到的那样,我正在从Page_Load事件中调用执行此过程的方法。 Could it be that the page hasn't fully loaded and I'm using its OutputStream? 可能是页面没有完全加载,我正在使用它的OutputStream吗? I'm not sure about it, because it doesn't crash on any line related to it, the PdfWriter line, for example. 我不确定,因为它不会在与其相关的任何行(例如PdfWriter行)上崩溃。

UPDATE As suggested, I'm showing how I insert text, since it could be related to the font. 更新正如所建议的,我正在展示如何插入文本,因为它可能与字体有关。

public void AddTextToParagraph(TextPDF text)
    {
        BaseFont baseFont = BaseFont.CreateFont(text.FontTypeName, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Font theFont = new Font(baseFont, text.Size, text.Style, new Color(text.FontColor));
        Chunk myContent = new Chunk(text.Text, theFont);
        this.theParagraph.Add(myContent);
    }

This I have in a class that has all the variables used, which are int and string (and the colour). 我在一个类中具有所有使用的变量,它们是int和string(以及颜色)。 After adding I debug theParagraph to see its content and everything is there. 添加后,我调试theParagraph以查看其内容以及所有内容。

The reference to the font is from the page with MapPath("~/Fonts/AlexanderSans.ttf"); 对字体的引用来自具有MapPath(“〜/ Fonts / AlexanderSans.ttf”)的页面; ... Come to think of it, the font is something the end user purchased (yes, they paid for it), not Arial or any other standard font. ...想一想,字体是最终用户购买的(是的,他们为此付费),而不是Arial或任何其他标准字体。 But it is a TTF which I also use in Excel while exporting other files in the same application, so the file is not corrupted. 但这是我在Excel中同时在同一应用程序中导出其他文件时使用的TTF,因此文件没有损坏。

Anyway, this is starting to be anoying, isn't it? 无论如何,这开始变得烦人了,不是吗? =) =)

Turns out mkl is right. 原来mkl是正确的。 Nothing to do with the stream nor the page. 与流或页面无关。 I simply changed the font oa standard Arial.ttf and work on the first try. 我只是简单地将字体更改为标准Arial.ttf并进行第一次尝试。 The error never made a reference to anything at all but a null reference. 该错误从未引用任何东西,只有空引用。

Why is the font a problem when you what to close the file, but not when you embed it to a text? 为什么在关闭文件时字体会出现问题,而在将其嵌入文本时却不会出现问题? Only the shadow knows. 只有影子知道。 "If what's logical doesn't work, try the illogical", right? “如果逻辑上不可行,请尝试不逻辑”,对吗?

Thanks to everyone, though. 谢谢大家。

Could you try this: 您可以尝试一下:

using (Document docPDF = new Document(PageSize.LETTER, this.LM, this.RM, this.TM, this.BM))
{
    this.writer = PdfWriter.GetInstance(docPDF, this.thePage.Response.OutputStream);

    docPDF.Open();

    for (int i = 0; i < elements.Count; i++)
    {
        docPDF.Add(elements[i]);
    }

    thePage.Response.HeaderEncoding = System.Text.Encoding.Default;
    thePage.Response.ContentType = "application/pdf; charset=utf-8";
    thePage.Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
    thePage.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    thePage.Response.Write(docPDF);
    thePage.Response.Flush();
    thePage.Response.End();
}

The using statement will call Dispose method of the Document. using语句将调用Document的Dispose方法。 I checked the source code and the Dispose is implemented like this: 我检查了源代码,并以如下方式实现了Dispose:

public virtual void Dispose() {
    if (IsOpen()) {
        Close();
    }
}

So it should close the document once it leaves the using block. 因此,一旦它离开了using块,就应该关闭该文档。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM