簡體   English   中英

iTextSharp在關閉文檔時引發異常

[英]iTextSharp throws exception at closing document

我在ASP.NET中使用Webforms的C#中的以下代碼遇到問題。 我花了很長時間尋找答案,但到目前為止還沒有運氣。

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

我在docPDF.Close()處收到NullReferenceException。

使用“ this”關鍵字的所有變量都已初始化,而在調試時它們確實顯示值。

我在其他項目中使用了完全相同的代碼,相同的庫(DLL),但這一次它根本無法正常工作。 elements數組是一個List <IElement>,我用PdfPTable,Paragraph,Chunk和Image對象填充。 當我調試它時,它們在那里。

打開我正在寫的文件時沒有錯誤,添加元素時沒有錯誤,我檢查文件是否打開,然后嘗試關閉它,但是它根本不會關閉。

如果我注釋掉該行,則不會引發任何異常,但是該文件會保存有錯誤,並且不會打開以供讀取。

有任何想法嗎?

更新這是堆棧跟蹤。 如您所見,它是第246行,並遵循堆棧跟蹤,它確實說這是Close()方法。 實際上,我開始崩潰后添加了“ if(docPDF.IsOpen())”部分。 對其進行調試,的確到達了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

另一件事,也許值得一提的是,在我開始更改代碼之前,要對此事有任何想法,但是正如您在堆棧中所看到的那樣,我正在從Page_Load事件中調用執行此過程的方法。 可能是頁面沒有完全加載,我正在使用它的OutputStream嗎? 我不確定,因為它不會在與其相關的任何行(例如PdfWriter行)上崩潰。

更新正如所建議的,我正在展示如何插入文本,因為它可能與字體有關。

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

我在一個類中具有所有使用的變量,它們是int和string(以及顏色)。 添加后,我調試theParagraph以查看其內容以及所有內容。

對字體的引用來自具有MapPath(“〜/ Fonts / AlexanderSans.ttf”)的頁面; ...想一想,字體是最終用戶購買的(是的,他們為此付費),而不是Arial或任何其他標准字體。 但這是我在Excel中同時在同一應用程序中導出其他文件時使用的TTF,因此文件沒有損壞。

無論如何,這開始變得煩人了,不是嗎? =)

原來mkl是正確的。 與流或頁面無關。 我只是簡單地將字體更改為標准Arial.ttf並進行第一次嘗試。 該錯誤從未引用任何東西,只有空引用。

為什么在關閉文件時字體會出現問題,而在將其嵌入文本時卻不會出現問題? 只有影子知道。 “如果邏輯上不可行,請嘗試不邏輯”,對嗎?

謝謝大家。

您可以嘗試一下:

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

using語句將調用Document的Dispose方法。 我檢查了源代碼,並以如下方式實現了Dispose:

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

因此,一旦它離開了using塊,就應該關閉該文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM