iTextSharp: Page header out of alignment with larg

2020-05-08 07:50发布

I am using the latest version of iTextSharp (5.4.3). When defining an even simple page header the header gets out of vertical alignment if the document contains large tables that do not fit on one page. The alignment on the first page a large table is displayed is fine, but on subsequent pages the header is displayed further down and overlays the table.

My code is below. Would be nice to get a workaround or an idea what could be wrong.

By the way: When adding paragraphs that cause an automatic page break I get the page headers as expected.

Here's my test code:

const string pdfFileName = "iTestSharp Table Split Test.pdf";
using (var pdfFileStream = File.Create(pdfFileName))
{
   using (Document document = new Document(PageSize.A4, 25, 25, 30, 30))
   {
      PdfWriter pdfWriter = PdfWriter.GetInstance(document, pdfFileStream);
      pdfWriter.PageEvent = new PageEventHelper();
      document.Open();  

      // When adding a large table the page heading for pages automatically created 
      // by the table are  out of alignment
      const int numberOfRows = 50;
      PdfPTable table = new PdfPTable(1)
      {
         TotalWidth = document.PageSize.Width - document.LeftMargin - document.RightMargin,
         LockedWidth = true
      };
      for (int i = 1; i <= numberOfRows; i++)
      {
         table.AddCell(i.ToString());
      }
      document.Add(table);

      // Adding more paragraphs than fit on one page creates page headers as expected
      document.NewPage();
      for (int i = 1; i <= numberOfRows; i++)
      {
         document.Add(new Paragraph("Line " + i));
      }
   }
} 

And here's the (very simple) PageEventHelper class:

public class PageEventHelper : PdfPageEventHelper
{
   public override void OnStartPage(PdfWriter writer, Document document)
   {
      base.OnStartPage(writer, document); // Does actually nothing
      document.Add(new Paragraph("Page Heading"));
   }
}

Result Page 1:

Result Page 1

Result Page 2: Result Page 2 Edit:

LineSeparators added in PdfPageEventHelper.OnStartPage are displayed correctly as long as they are not inside a Chunk. Chunk and Paragraph objects get out of alignment (even if a LineSeparator is before and/or after them). It looks like paragraphs are correctly added (the lines are in the header) but only the text inside them is printed out in a wrong place.

标签: itextsharp
1条回答
三岁会撩人
2楼-- · 2020-05-08 08:27

In OnStartPage and OnEndPage you are not supposed to add anything to the given Document instance. Instead headers and footers shall be added to the direct content of the given PdfWriter. Cf. The iText(Sharp) samples, e.g.

  /**
   * Adds the header and the footer.
   * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
   *      com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
   */
  public override void OnEndPage(PdfWriter writer, Document document) {
    Rectangle rect = writer.GetBoxSize("art");
    switch(writer.PageNumber % 2) {
    case 0:
      ColumnText.ShowTextAligned(writer.DirectContent,
        Element.ALIGN_RIGHT, 
        header[0],
        rect.Right, rect.Top, 0
      );
      break;
    case 1:
      ColumnText.ShowTextAligned(
        writer.DirectContent,
        Element.ALIGN_LEFT,
        header[1],
        rect.Left, rect.Top, 0
      );
      break;
    }
    ColumnText.ShowTextAligned(
      writer.DirectContent,
      Element.ALIGN_CENTER, 
      new Phrase(String.Format("page {0}", pagenumber)),
      (rect.Left + rect.Right) / 2, 
      rect.Bottom - 18, 0
    );
  }

(from MovieHistory2.cs, a C#'ified sample from chapter 5 of iText in Action — 2nd Edition)

查看更多
登录 后发表回答