PDFsharp: Is there a way to generate "Page X of Y" in the header of the page?
Asked Answered
P

5

36

It seems rather simple, but I can't find something like getPageCount() in the API. I can get it to return the current page, but not the total number of pages. Perhaps I'm missing it?

I would like to somehow be able to print 'Page 1 of 9' at the top of every page, where '1' of course is the current page number.

Prentice answered 21/10, 2013 at 15:36 Comment(1)
Could you show some code please?Prothallus
F
30

With PDFsharp it's up to you.

I presume you are using MigraDoc: With MigraDoc you can add a page header. Add paragraph.AddPageField() for the current page number and paragraph.AddNumPagesField() for the total page count.

Sample that uses AddPageField

Code snippet from the sample:

// Create a paragraph with centered page number. See definition of style "Footer".
Paragraph paragraph = new Paragraph();
paragraph.AddTab();
paragraph.AddPageField();

// Add paragraph to footer for odd pages.
section.Footers.Primary.Add(paragraph);
// Add clone of paragraph to footer for odd pages. Cloning is necessary because an object must
// not belong to more than one other object. If you forget cloning an exception is thrown.
section.Footers.EvenPage.Add(paragraph.Clone());

Code snippet that sets the tab stop (assuming DIN A 4 with a body with of 16 cm):

style = document.Styles[StyleNames.Footer]; 
style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center); 

Both snippets taken from the linked site. Sample code is also available for download.

Flatfoot answered 21/10, 2013 at 15:55 Comment(5)
Sample showed at this page doesn't work well. I mean that page number doesn't change.Fulguration
@Marek Bar: AddNumPagesField adds the number of pages in the document (and does not change between pages), AddPageField adds the current page number and changes from page to page.Flatfoot
@PDFsharpTeam... if I want to display page number ONLY if the PDF is MORE than a page long... how should I do it? Now, my PDF display "Pag: 1" even if I have one page total.Lucretialucretius
@Romias: In the first run create the document for the most likely case (e.g. without footer if a single page is more likely than multiple pages). If the PDF is not as expected (e.g. more than one page) then throw it away and create a new document with footer. Or always create it with footer and use PDFsharp to draw a white rectangle over the footer if it is a single page (that's a hack). Or always create it without footer and use PDFsharp to draw the footer if needed.Flatfoot
Works perfectly :)Goby
H
34

Make sure to include the using MigraDoc.DocumentObjectModel; statement in your class.

Document document = new Document();
Section section = document.AddSection();

Paragraph paragraph = new Paragraph();
paragraph.AddText("Page ");
paragraph.AddPageField();
paragraph.AddText(" of ");
paragraph.AddNumPagesField();

section.Headers.Primary.Add(paragraph);
Hienhieracosphinx answered 18/6, 2015 at 20:9 Comment(2)
What is this MigraDoc and where do I get it? I'm using PdfSharp, like the questions states. I don't have a Document only a PdfDocumentGatha
@sLw MigraDoc is a layer on top of PDFsharp which provides an object-oriented approach to creating PDFs. Simplifies PDF design IMO. See pdfsharp.net for more info.Hienhieracosphinx
F
30

With PDFsharp it's up to you.

I presume you are using MigraDoc: With MigraDoc you can add a page header. Add paragraph.AddPageField() for the current page number and paragraph.AddNumPagesField() for the total page count.

Sample that uses AddPageField

Code snippet from the sample:

// Create a paragraph with centered page number. See definition of style "Footer".
Paragraph paragraph = new Paragraph();
paragraph.AddTab();
paragraph.AddPageField();

// Add paragraph to footer for odd pages.
section.Footers.Primary.Add(paragraph);
// Add clone of paragraph to footer for odd pages. Cloning is necessary because an object must
// not belong to more than one other object. If you forget cloning an exception is thrown.
section.Footers.EvenPage.Add(paragraph.Clone());

Code snippet that sets the tab stop (assuming DIN A 4 with a body with of 16 cm):

style = document.Styles[StyleNames.Footer]; 
style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center); 

Both snippets taken from the linked site. Sample code is also available for download.

Flatfoot answered 21/10, 2013 at 15:55 Comment(5)
Sample showed at this page doesn't work well. I mean that page number doesn't change.Fulguration
@Marek Bar: AddNumPagesField adds the number of pages in the document (and does not change between pages), AddPageField adds the current page number and changes from page to page.Flatfoot
@PDFsharpTeam... if I want to display page number ONLY if the PDF is MORE than a page long... how should I do it? Now, my PDF display "Pag: 1" even if I have one page total.Lucretialucretius
@Romias: In the first run create the document for the most likely case (e.g. without footer if a single page is more likely than multiple pages). If the PDF is not as expected (e.g. more than one page) then throw it away and create a new document with footer. Or always create it with footer and use PDFsharp to draw a white rectangle over the footer if it is a single page (that's a hack). Or always create it without footer and use PDFsharp to draw the footer if needed.Flatfoot
Works perfectly :)Goby
P
29

I know this question is old and has an accepted answer, however the question comes up among the first when searching for a PDFsharp solution.

For the record, achieving this in PDFsharp is easy. The PdfDocument class, found under the PdfSharp.Pdf namespace contains a collection of pages (PdfDocument.Pages). All you have to do is iterate through the collection and add the page counter somewhere on every page, using a XGraphics object, that you can instantiate using XGraphics.FromPdfPage(PdfPage).

using PdfSharp.Pdf; // PdfDocument, PdfPage
using PdfSharp.Drawing; // XGraphics, XFont, XBrush, XRect
                        // XStringFormats

// Create a new PdfDocument.
PdfDocument document = new PdfDocument();
// Add five pages to the document.
for(int i = 0; i < 5; ++i)
    document.AddPage();

// Make a font and a brush to draw the page counter.
XFont font = new XFont("Verdana", 8);
XBrush brush = XBrushes.Black;

// Add the page counter.
string noPages = document.Pages.Count.ToString();
for(int i = 0; i < document.Pages.Count; ++i)
{
    PdfPage page = document.Pages[i];

    // Make a layout rectangle.
    XRect layoutRectangle = new XRect(0/*X*/, page.Height-font.Height/*Y*/, page.Width/*Width*/, font.Height/*Height*/);

    using (XGraphics gfx = XGraphics.FromPdfPage(page))
    {
        gfx.DrawString(
            "Page " + (i+1).ToString() + " of " + noPages,
            font,
            brush,
            layoutRectangle,
            XStringFormats.Center);
    }
}

It's worth noting that if a XGraphics object already exists for a given page, before creating a new one, the old one needs to be disposed. This would fail:

PdfDocument document = new PdfDocument();
PdfPage page = document.AddPage();

XGraphics gfx1 = XGraphics.FromPage(page);
XGraphics gfx2 = XGraphics.FromPage(page);
Pedestal answered 25/1, 2016 at 17:10 Comment(0)
G
1

It is worth noting that AddSectionPagesField() also exists. In this way 'Y' will be the number of pages of the section instead of the number of pages of the entire document.

It finds its use when you generate many different documents for one print and you want to separate page counting. I hope it is understandable.

So then you can also use:

            Paragraph paragraph = new Paragraph();
            paragraph.AddText("Page");
            paragraph.AddPageField();
            paragraph.AddText(" of ");
            paragraph.AddSectionPagesField();

            // Add paragraph to header for odd pages.
            section.Headers.Primary.Add(paragraph);
            // Add clone of paragraph to header for odd pages. Cloning is necessary because an object must
            // not belong to more than one other object. If you forget cloning an exception is thrown.
            section.Headers.EvenPage.Add(paragraph.Clone());

Similarly just for footer use:

            section.Footers.Primary.Add(paragraph);
            section.Footers.EvenPage.Add(paragraph.Clone());
Gilbert answered 15/6, 2020 at 12:45 Comment(0)
N
-2

here's how you can fix it

        Paragraph foot = sec.Footers.Primary.AddParagraph();
        foot.AddText("Page ");
        foot.AddPageField();
        foot.AddText(" of ");
        foot.AddNumPagesField();
Numerous answered 7/12, 2020 at 3:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.