Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
491 views
in Technique[技术] by (71.8m points)

itextsharp - Page X of Y issue

I tried 3 different ways of displaying Page numbers, OnCloseDocument content is not displaying in the page, none of them worked.

My Intention is displaying Page numbers like this

1 of 10
2 0f 10
..............
............
10 of 10 on each page

I know how to display

1
2
3
4
....
10

but don`t know how to display total page number

I`m using OnCloseDocument to display No.of pages count,but the content in it is not displaying.

public class MyPdfPageEventHelpPageNo : iTextSharp.text.pdf.PdfPageEventHelper
{
    protected PdfTemplate total;
    protected BaseFont helv;
    private bool settingFont = false;

    public override void OnOpenDocument(PdfWriter writer, Document document)
    {
        template= writer.DirectContent.CreateTemplate(100, 100);       

        bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED);
    }
    public override void OnCloseDocument(PdfWriter writer, Document document)
    {
    //See below
    }

1ST WAY:

    public override void OnCloseDocument(PdfWriter writer, Document document)     
    {
        //I create a table with one column like below.
        PdfPTable pageNumber2 = new PdfPTable(1);
        pageNumber2.TotalWidth = 50;
        pageNumber2.HorizontalAlignment = Element.ALIGN_RIGHT;

        pageNumber2.AddCell(BuildTable2RightCells("Page " + writer.PageNumber));
        pageNumber.AddCell(BuildTable2LeftCells(writer.PageCount));
        pageNumber2.WriteSelectedRows(0, -1, 500, 
        (document.PageSize.GetBottom(140)), cb);
    }    

2ND WAY:

    public override void OnCloseDocument(PdfWriter writer, Document document)     
    {
        ColumnText.ShowTextAligned(template,Element.ALIGN_CENTER,new
        Phrase(writer.PageNumber.ToString()), 500, 140, 0);
    }

3RD WAY:

    public override void OnCloseDocument(PdfWriter writer, Document document)     
    {
        template.BeginText();
        template.SetFontAndSize(bf, 8);
        template.SetTextMatrix(500, 140);
        template.ShowText(Convert.ToString((writer.PageNumber - 1)));
        template.EndText();
    }

Am I doing anything wrong?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Your second way is probably the simplest way. Below is a very, very slimmed down but working version:

public class MyPdfPageEventHelpPageNo : iTextSharp.text.pdf.PdfPageEventHelper {
    public override void OnEndPage(PdfWriter writer, Document document) {
        ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_CENTER, new Phrase(writer.PageNumber.ToString()), 500, 140, 0);
    }
}

And to use it:

//Create a file on our desktop
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "OnCloseTest.pdf");
//Standard PDF creation, adjust as needed
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    using (Document doc = new Document(PageSize.LETTER)) {
        using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {

            //Find our custom event handler
            writer.PageEvent = new MyPdfPageEventHelpPageNo();

            doc.Open();

            //Add text the first page
            doc.Add(new Paragraph("Test"));

            //Add a new page with more text
            doc.NewPage();
            doc.Add(new Paragraph("Another Test"));

            doc.Close();
        }
    }
}

EDIT

Sorry, I thought that you were having problems with the basic setup of events, my mistake.

I've only seen two ways to do what you are trying to do, either do two passes or use the PdfTemplate syntax which renders an image as far as I know.

I'd recommend just running two passes, the first just to create your PDF and the second to add your page numbers. You can run your first pass to a MemoryStream so you don't have to hit the disk twice if you want.

PdfReader reader = new PdfReader(outputFile);
using (FileStream fs = new FileStream(secondFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
    using (PdfStamper stamper = new PdfStamper(reader, fs)) {
        int PageCount = reader.NumberOfPages;
        for (int i = 1; i <= PageCount; i++) {
            ColumnText.ShowTextAligned(stamper.GetOverContent(i), Element.ALIGN_CENTER, new Phrase(String.Format("Page {0} of {1}", i, PageCount)), 500, 140, 0);
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...