[英]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.