iTextSharp在关闭文档时抛出异常
本文关键字:抛出异常 文档 iTextSharp | 更新日期: 2023-09-27 18:01:40
我在使用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();
所有使用"this"关键字的变量都已初始化,在调试时它们会显示值。
我在其他项目中使用完全相同的代码,相同的库(DLL),但这次它根本不起作用。元素数组是一个List<我填充PdfPTable,段落,块和图像对象。当我调试它时,它们就在那里。>
在打开我正在写的文件时没有错误,当我添加元素时没有错误,我检查文件是否打开,然后尝试关闭它,但它根本不会关闭。
如果我注释掉这行,不会抛出异常,但文件被错误保存,不会打开以读取。
任何想法?
下面是堆栈跟踪。正如您所看到的,它在第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(和颜色)。添加后,我调试段落,看看它的内容,一切都在那里。
对字体的引用来自MapPath("~/Fonts/AlexanderSans.ttf");…仔细想想,字体是最终用户购买的(是的,他们为此付费),而不是Arial或任何其他标准字体。但它是一个TTF,我也在Excel中使用,同时在同一应用程序中导出其他文件,所以文件没有损坏。
不管怎样,这开始让人讨厌了,不是吗?div =)结果证明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块。