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,并进行了第一次尝试。这个错误除了一个空引用之外没有引用任何东西。

为什么字体是一个问题,当你关闭文件,但不是当你嵌入到一个文本?只有影子知道。"如果合乎逻辑的不起作用,那就试试不合逻辑的"对吧?

谢谢大家

iTextSharp在关闭文档时抛出异常

你可以试试这个吗:

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块。