Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

put page number when create PDF with iTextSharp

I'm working with ASP MVC and i use iTextSharp to generate PDF's in my application. But now i have a problem: I printing lists and when exist more than one page, i want to show the page number (ex.: Page 1 to 4). I found some examples, but i think it is more complexes than i need to do (like exameple).

EDIT: I found this example 2. I can count number of pages, but i cant print the number in pages.

What i did:

public ActionResult downloadListaISCC(DateTime? DataFimFiltro)
{

//Code to generate list to PDF

   //My document
   Document doc1 = new Document();
   doc1.SetPageSize(iTextSharp.text.PageSize.A4);
   doc1.SetMargins(0f, 0f, 0f, 0f);
   doc1.NewPage();

   MemoryStream pdfStream = new MemoryStream();
   PdfWriter pdfWriter = PdfWriter.GetInstance(doc1, pdfStream);

   //Code to create table
   doc1.Add(table); //table list in document

   //Follow the example 2 (link)
   pdfWriter.CloseStream = true;
   doc1.Close();


   //E fui seguindo o exemplo do segundo link
   string file = "D:/gerarPDFOleotorres/"+ nomeDoc +""; 

   // add page numbers
   Document copyDoc = new Document();
   PdfCopy copyPdf = new PdfCopy(copyDoc, new FileStream(file, FileMode.Create));
   copyPdf.SetPageSize(PageSize.A4.Rotate());
   copyDoc.Open();

   // read the initial pdf document
   PdfReader reader = new PdfReader(pdfStream.ToArray());
   int totalPages = reader.NumberOfPages;

   PdfImportedPage copiedPage = null;
   iTextSharp.text.pdf.PdfCopy.PageStamp stamper = null;

   for (int i = 0; i < totalPages; i++)
   {

       // get the page and create a stamper for that page
       copiedPage = copyPdf.GetImportedPage(reader, (i + 1));
       stamper = copyPdf.CreatePageStamp(copiedPage);

       // add a page number to the page
       ColumnText.ShowTextAligned(stamper.GetUnderContent(), Element.ALIGN_CENTER, new Phrase((i + 1) + "/" + totalPages, fontetexto), 820f, 15, 0);
        stamper.AlterContents();

       // add the altered page to the new document
       copyPdf.AddPage(copiedPage);
   }

   copyDoc.Close();
   reader.Close();

   // flush and clear the document from memory
   pdfStream.Flush();
   pdfStream.Close();
    }
like image 480
CesarMiguel Avatar asked Apr 02 '14 09:04

CesarMiguel


Video Answer


1 Answers

Basically, you have two options: either you create the document in one go, or you create the document in two passes.

If you create the document in one go, you don't know the value of Y (the total number of pages) in advance, so you need to create a PdfTemplate object as a place holder. This is demonstrated in the MovieCountries1 example.

In this example, we create a TableHeader class that extends PdfPageEventHelper. We create an instance of the PdfTemplate class for the total in the OnOpenDocument() method, we use this total placeholder in the OnEndPage() method where we add the header or footer, and we fill out the total number of pages in the OnCloseDocument() method.

The disadvantage of this approach is that it's something hard to predict the dimensions needed for total. The advantage is that you can create the document in one go (you don't need to create the document in memory first).

If you create the document in two passes, you create the document without header/footer first, and then you examine the document to find out how many pages it contains. Then you use PdfStamper to add the page numbers to each page. This is shown in the TwoPasses example.

These examples are taken from my book "iText in Action - Second Edition". You can download chapter 6 for free from this URL: http://manning.com/lowagie2/samplechapter6.pdf

Please consult the [official documentation][4] when you are in doubt about specific functionality.

Update: I don't understand why you prefer looking at unofficial examples. The example I gave you looks like this:

using (PdfStamper stamper = new PdfStamper(reader, ms2)) {
    // Loop over the pages and add a header to each page
    int n = reader.NumberOfPages;
    for (int i = 1; i <= n; i++) {
        // Add content
    }
}

Yet for some reason you Googled an example that is much more complex (and overkill for what you need).

Just replace the // Add content part with:

ColumnText.ShowTextAligned(stamper.GetUnderContent(), Element.ALIGN_CENTER, new Phrase((i + 1) + "/" + totalPages, fontetexto), 297f, 15f, 0);

Note that I adapted the x value in the ShowTextAligned() method. You're creating a page with size A4, which means your page is 595 user units wide. If you add page numbers at position x = 820, the footer will be added, but it will be outside the visible area of the page. Please don't copy/paste code without knowing the parameters of each method.

like image 190
Bruno Lowagie Avatar answered Nov 05 '22 04:11

Bruno Lowagie