0

I'm trying to make a PDF document with iTextSharp.

I don't know how to make a header with "currentPageNumber/documentsNumberOfPages" like that :

sample

Follow-up question

For the moment, based on the original answers, I have this :

public class StockComp : iTextSharp.text.pdf.PdfPageEventHelper
{
    PdfTemplate templateNumPage;

    public string Header
    {
        get;
        set;
    }

    public override void OnOpenDocument(PdfWriter writer, Document document)
    {
        templateNumPage = writer.DirectContent.CreateTemplate(30, 250);
    }

    public override void OnEndPage(PdfWriter writer, Document document)
    {
        PdfPTable table = new PdfPTable(3);
        try
        {
            table.SetWidths(new int[] { 10, 10, 2 });
            table.TotalWidth = 800;
            table.LockedWidth = true;
            table.DefaultCell.FixedHeight = 20;
            table.DefaultCell.Border = Rectangle.BOTTOM_BORDER;
            table.AddCell(Header);
            table.DefaultCell.HorizontalAlignment = Element.ALIGN_RIGHT;
            table.AddCell(string.Format("Page {0} of", writer.PageNumber));
            PdfPCell cell = new PdfPCell(Image.GetInstance(templateNumPage));
            cell.Border = Rectangle.BOTTOM_BORDER;
            table.AddCell(cell);
            table.WriteSelectedRows(0, -1, 34, 803, writer.DirectContent);
        }
        catch (DocumentException de)
        {
            throw de;
        }
    }

    public override void OnCloseDocument(PdfWriter writer, Document document)
    {
        ColumnText.ShowTextAligned(templateNumPage, Element.ALIGN_LEFT, new Phrase((writer.PageNumber - 1).ToString()), 2, 2, 0);
    }
}

But, I don't understant why, it's just show the "templateNumPage" and doesn't show the first and second cells which contains "Header" and "Page {0} of"...

I declare my document like this :

// On récupère le n ombre de lignes et de colonne de la GridView
        int noOfColumns = gvReportingStockComp.Columns.Count;
        int noOfRows = gvReportingStockComp.Rows.Count;

        // On fixe les informations concernant les tailles de police du document PDF
        float HeaderTextSize = 8;
        float ReportNameSize = 10;
        float ReportTextSize = 8;
        float ApplicationNameSize = 7;

        // --- On crée le document final --- \\
        Document document = null;
        // Le document final sera-t-il en mode paysage ou non
        bool LandScape = true;
        if (LandScape == true)
        {
            // Comme le document est en mode paysage, on execute une rotation sur ces dimensions
            // Les 4 derniers paramètres de la fonction correspondent aux marges du document sur les bords
            document = new Document(PageSize.A4.Rotate(), -50, -50, 50, 30);
        }
        else
        {
            // On spécifie les dimensions du document
            // Les 4 derniers paramètres de la fonction correspondent aux marges du document sur les bords
            document = new Document(PageSize.A4, 0, 0, 0, 0);
        }

        // --- On instancie le Writer et la classe d'evenement associée --- \\
        // Le flux de sortie
        PdfWriter pdfW = PdfWriter.GetInstance(document, Response.OutputStream);
        // La classe évenement associée
        StockComp evenement = new StockComp();
        pdfW.PageEvent = evenement;

        // --- Ouverture du document --- \\
        document.Open();

        // --- On ajoute les valeurs dans le document --- \\

        // On créer un PdfTable qui contient le même nombre de colonne que la GridView
        // On ajoute 3 car l'on souahite que la cellule composant ait une taille de 4
        // et le autre cellule une taille de 1.
        PdfPTable mainTable = new PdfPTable(noOfColumns+3); 

        // Notre document sera composé de au minimum 4 lignes :
        // 1 : Nom appli + Date
        // 2 : Titre du tableau
        // 3 : Saut de ligne
        // 4 : Headers du tableau
        // X : Lignes du tableau
        mainTable.HeaderRows = 4;

        evenement.Header = "Trèves";

        // On génère les noms de colonnes et on les insèrent
        for (int i = 0; i < noOfColumns; i++)
        {
            PdfPCell cell = null;

            Phrase ph = null;

            ph = new Phrase(gvReportingStockComp.Columns[i].HeaderText, FontFactory.GetFont("Tahoma", HeaderTextSize, iTextSharp.text.Font.BOLD));

            cell = new PdfPCell(ph);

            cell.HorizontalAlignment = Element.ALIGN_CENTER;

            if (i == 1)
            {
                cell.Colspan = 4;
            }

            mainTable.AddCell(cell);
        }

document.Add(mainTable);

//pdfW.PageNumber*/
document.Close();

Please, help me. Thanks ;)

mkl
  • 90,588
  • 15
  • 125
  • 265
user2265252
  • 65
  • 1
  • 5
  • 13

2 Answers2

0

I can't help you with the page header thing (also my computer's not showing the image for some reason...) but to get the page number in iTextSharp you can do:

iTextSharp.text.pdf.PdfReader pdfReader = new iTextSharp.text.pdf.PdfReader(documentImage);
// may want to check if pdfReader is null before doing below
int numPages = pdfReader.NumberOfPages;

Where documentImage is of type byte[], but you could use any of PdfReader's overloads.

aladd04
  • 439
  • 5
  • 14
0

The iText in Action — 2nd Edition example MovieCountries1.java / MovieCountries1.cs illustrates how to create a document with Page X/Y information.

The central construction brick is a PdfPageEventHelper adding header information:

/**
 * Inner class to add a table as header.
 */
protected class TableHeader : PdfPageEventHelper {
  /** The template with the total number of pages. */
  PdfTemplate total;

  /** The header text. */
  public string Header { get; set; }

  /**
   * Creates the PdfTemplate that will hold the total number of pages.
   */
  public override void OnOpenDocument(PdfWriter writer, Document document) {
    total = writer.DirectContent.CreateTemplate(30, 16);
  }

  /**
   * Adds a header to every page
   */
  public override void OnEndPage(PdfWriter writer, Document document) {
    PdfPTable table = new PdfPTable(3);
    try {
      table.SetWidths(new int[]{24, 24, 2});
      table.TotalWidth = 527;
      table.LockedWidth = true;
      table.DefaultCell.FixedHeight = 20;
      table.DefaultCell.Border = Rectangle.BOTTOM_BORDER;
      table.AddCell(Header);
      table.DefaultCell.HorizontalAlignment = Element.ALIGN_RIGHT;
      table.AddCell(string.Format("Page {0} of", writer.PageNumber));
      PdfPCell cell = new PdfPCell(Image.GetInstance(total));
      cell.Border = Rectangle.BOTTOM_BORDER;
      table.AddCell(cell);
      table.WriteSelectedRows(0, -1, 34, 803, writer.DirectContent);
    }
    catch(DocumentException de) {
      // ...
      throw de;
    }
  }

  /**
   * Fills out the total number of pages before the document is closed.
   */
  public override void OnCloseDocument(PdfWriter writer, Document document) {
    ColumnText.ShowTextAligned(
      total, Element.ALIGN_LEFT,
// NewPage() already called when closing the document; subtract 1
      new Phrase((writer.PageNumber - 1).ToString()),
      2, 2, 0
    );
  }
}

It is employed like this:

// step 1
using (Document document = new Document(PageSize.A4, 36, 36, 54, 36)) {
  // step 2
  PdfWriter writer = PdfWriter.GetInstance(document, stream);
  TableHeader tevent = new TableHeader();
  writer.PageEvent = tevent;
  // step 3
  document.Open();
  [...]
}

Beware: The table written by the OnEndPage code above is formatted for a portrait A4 document. If you use a landscape document size, you have to adjust some of the values, namely the TotalWidth value 527 and the writing coordinates 34, 803 of table.WriteSelectedRows as otherwise your header may be partially off-page.

There is also an alternative. Cf. Keyword: Page numbers > page X of Y.

mkl
  • 90,588
  • 15
  • 125
  • 265
  • Thanks, I have edit my post because I have an other question :/ – user2265252 Jun 25 '13 at 09:23
  • Editing a question like that is very bad style. Now none of the comments and answers seem to fit anymore. Whenever you have other questions, create a new question. Or at least, if the questions are connected, leave the original question text and add the other question titled as e.g. "follow-up question" underneath. – mkl Jun 25 '13 at 09:59
  • Concerning your problems, though, I added a warning in my answer concerning the table width and position hard-coded into the sample; if you are using a different document format, you have to adjust those hard-coded values, too. Your code currently uses A4 landscape. Thus, the cells you are missing quite likely are located above the page border. Furthermore you use negative margins. I doubt you'll be happy with them in the long run. – mkl Jun 25 '13 at 10:20
  • Furthermore you seem add only cells for two columns. The table has three! The third one for width cosmetics, I assume. – mkl Jun 25 '13 at 10:32
  • Thanks, I will trying it. And sorry for my post edition, I don't understand correctly the rules for this forum ;) – user2265252 Jun 25 '13 at 12:05