【问题标题】:Getting a Stack Overflow Exception generating a PDF [duplicate]获取生成 PDF 的堆栈溢出异常 [重复]
【发布时间】:2015-06-02 17:33:28
【问题描述】:

作为我earlier question 的延续,我一直在尝试我的PDF 的页眉和页脚功能。经过一番讨论后,我在 PdfPageEventHelper 类上更改了很多代码。以下是我所拥有的:

public class ReportHeaderFooter : PdfPageEventHelper
{
    public string HeaderTitle { get; set; }
    public IReportsAccessor ReportsAccessor { get; set; }
    private Image footerImg;
    private Image headerImg;
    private BaseColor headerColor;
    private PdfPTable tblHeader;
    public ReportHeaderFooter(IReportsAccessor reportsAccessor)
    {
        this.ReportsAccessor = reportsAccessor;
        var rootPath = ConfigurationManager.AppSettings["SaveFileRootPath"];
        headerColor = new BaseColor(System.Drawing.ColorTranslator.FromHtml("#ffffff")); // Not really but I don't want to give away the color

    }

    public override void OnOpenDocument(PdfWriter writer, Document document)
    {
        base.OnOpenDocument(writer, document);
        // Set the initial header image...
        var headerImgInfo = ReportsAccessor.GetImage(4);
        headerImg = Image.GetInstance(headerImgInfo.ReportImage);

        // Set the initial footer image...
        var footerImgInfo = ReportsAccessor.GetImage(2);
        footerImg = Image.GetInstance(footerImgInfo.ReportImage);

        // Create the header table...
        tblHeader = new PdfPTable(2)
        {
            TotalWidth = document.Right,
        };
        tblHeader.SetWidths(new float[2] { document.Right - 70f, 70f });
        PdfPCell titleCell = new PdfPCell(new Phrase(HeaderTitle))
        {
            BackgroundColor = headerColor
        };
        tblHeader.AddCell(titleCell);
        PdfPCell imgCell = new PdfPCell(headerImg)
        {
            BackgroundColor = headerColor,
            HorizontalAlignment = PdfPCell.ALIGN_RIGHT,
        };
        tblHeader.AddCell(imgCell);
    }

    public override void OnEndPage(PdfWriter writer, Document document)
    {
        base.OnEndPage(writer, document);
        // Add the header table to the tops of the documents...
        document.Add(tblHeader);

        // Create the image at the footer.
        footerImg.SetAbsolutePosition(0, document.Bottom);
        document.Add(footerImg);            
    }

但是,当我到达其中一页的 document.Add(tblHeader) 行时(这是一个相当大的 pdf(可能有 10 页))。我得到一个堆栈溢出异常)。

我在这里做错了什么(如果有的话)?我问的最后一个问题是我收到了礼貌的 RTM,但是,在阅读了大量文档后,我不明白为什么一些相对简单的事情会导致堆栈溢出。请帮我理解。

【问题讨论】:

  • 如果不运行您的代码,我的猜测是您的 document.Add(tblHeader); 会导致添加一个新页面,这会导致调用 OnEndPage,这会导致添加一个新页面,这会导致 OnEndPage被调用,导致添加新页面,导致调用OnEndPage,导致添加新页面,导致调用OnEndPage,导致添加新页面,导致OnEndPage调用导致添加新页面导致调用OnEndPage导致添加新页面导致调用OnEndPage...
  • 也就是说……每当调用OnEndPage时,页面已经满了,此时你不能再在页面上添加自动布局的内容了。因此,在该方法中调用document.Add 只会失败。查看使用 iText 页面事件的无数示例,尤其是那些在 stackoverflow 或 iText 网站上的示例。
  • 所以你是说两个单元格的表格对于页面来说可能太大了。我会看看(如果我删除页脚并运行它会发生什么)并在这里报告。我不确定无数的例子会做什么,因为我已经检查过了。
  • 这些示例中最重要的部分是它们几乎总是在特定位置添加内容,而不是依赖抽象层来解决问题。我会调查 ColumnTextPdfPTable.WriteSelectedRows()

标签: c# pdf itextsharp


【解决方案1】:

如官方文档中所述,严格禁止在页面事件中向document 对象添加内容。 document 对象不是您在主代码中使用的 Document 对象。相反,它是一个内部 PdfDocument 实例,它被传递给事件以用于只读目的。

如果要在页面事件中添加表格,则应使用writeSelectedRows() 方法。请下载免费电子书The Best iText Questions on StackOverflow 并查看有关事件的章节。

您会找到对以下问题的参考:

阅读免费提供的文档可以为您(和我们)节省大量时间;-)

【讨论】:

  • 正如官方文档中提到的,在页面事件中严格禁止向文档对象添加内容。 - 你应该开始在那里抛出异常。
猜你喜欢
  • 2012-09-22
  • 2020-11-14
  • 2021-04-07
  • 2017-03-31
  • 2010-11-27
  • 2010-12-08
相关资源
最近更新 更多