2015-06-02 3 views
2

В качестве продолжения для моего earlier question Я пытался использовать функции верхнего и нижнего колонтитулов для моего PDF-файла. После небольшой дискуссии я изменил довольно много кода в классе PdfPageEventHelper. Ниже то, что у меня есть:Получение исключения переполнения стека, генерирующего PDF

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, однако, прочитав много документации, я не понимаю, почему что-то относительно простое вызывает переполнение стека. Пожалуйста, помогите мне понять.

+0

Не запуская свой код, я предполагаю, что ваш 'document.Add (tblHeader);' вызывает добавление новой страницы, которая вызывает вызов OnEndPage, который вызывает добавление новой страницы, что вызывает 'OnEndPage' который вызывает добавление новой страницы, которая вызывает вызов «OnEndPage», который вызывает добавление новой страницы, которая вызывает вызов «OnEndPage», который вызывает добавление новой страницы, что приводит к тому, что «OnEndPage» который вызывает добавление новой страницы, которая вызывает вызов «OnEndPage», который вызывает добавление новой страницы, которая вызывает вызов «OnEndPage» ... –

+0

Другими словами ... всякий раз, когда вызывается «OnEndPage», страница уже заполнена, в это время вы больше не можете добавлять контент для автоматического макетирования на странице. Таким образом, вызов метода document.Add в этом методе может завершиться неудачей. Посмотрите на множество примеров, используя события страницы iText, особенно те, которые находятся в stackoverflow или на веб-сайте iText. – mkl

+0

Итак, вы говорите, что таблица с двумя ячейками, вероятно, слишком велика для страницы. Я посмотрю (если я удалю нижний колонтитул и запустил его, что происходит) и отчитайтесь здесь. Я не совсем уверен, что будет делать множество примеров, как я уже проверил их. –

ответ

1

Как указано в официальной документации, строго запрещено, чтобы добавить содержимое к объекту document в событие страницы. Это document объект не объект Document, который вы используете в своем основном коде. Вместо этого это внутренний экземпляр PdfDocument, который передается событию для только для чтения целей.

Если вы хотите добавить таблицу в событие страницы, вы должны использовать метод writeSelectedRows(). Загрузите бесплатную электронную книгу The Best iText Questions on StackOverflow и посмотрите главу о событиях.

Вы найдете ссылки на следующие вопросы:

Чтение документации, доступной бесплатно, может сэкономить вам (и нам) много времени ;-)

+1

* Как уже упоминалось в официальной документации, категорически запрещено добавлять контент в объект документа в событие страницы. * - вы должны начать бросать исключения там. – mkl

Смежные вопросы