【发布时间】:2015-07-09 04:38:26
【问题描述】:
我在使用 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),但这次它根本不起作用。元素数组是一个 List
打开我正在编写的文件时没有错误,当我添加元素时没有错误,我检查文件是否打开然后尝试关闭它,但它根本不会关闭。
如果我注释掉该行,则不会引发异常,但文件会保存错误并且不会打开以供阅读。
有什么想法吗?
更新 这是堆栈跟踪。如您所见,它是第 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 或任何其他标准字体。但它是一个 TTF,我也在 Excel 中使用它,同时在同一个应用程序中导出其他文件,因此文件没有损坏。
不管怎样,这开始很烦人了,不是吗? =)
【问题讨论】:
-
试试这个 if (docPDF.IsOpen()==true) docPDF.Close();
-
发布的代码片段似乎正在工作,没有抛出 NullReference 异常。看看this answer 能不能解决你的问题?
-
我得到一个 NullReferenceException - 你能提供那个异常的堆栈跟踪吗?
-
@mkl 我已经用堆栈跟踪和有关 Page_Load 事件的内容更新了问题。请检查一下。
-
我强烈建议您不要直接写信给
Response.OutputStream,而是写信给MemoryStream,当PDF 完全完成后获取字节class="comcopy"> i> 然后写那些。您的代码是 100% 有效的,但Response.OutputStream由其他可能正在做您不期望的事情的“拥有”,而MemoryStream是“您的,只有您的”。一旦你完成了这种分离,你可能会发现将 NRE 隔离到真正的 iText 或真正的 ASP.Net 会更容易
标签: c# itextsharp nullreferenceexception