Add a page number in the footer of a PDF file using iText7 and ASP.NET C#

I can create a pdf file using iText7 and C# ASP.NET

This pdf file contains 9 pages total.

I have tried to add in my code the total number of pages and a dotted line

But I have two problems

  1. the number of pages (1 of 9, 2 of 9, 3 of 9…) are showing only in the pages number 8 and number 9 in the PDF file
  2. the dotted line don’t showing in page number one…

Any help would greatly appreciate… Thank you.

My code below

private void mtpdfnew()
{
    DataTable dt = new DataTable();

    filename = @"C:inetpubwwwrootpublicpdf" +
        DateTime.Now.ToString("yyyyMMddHHmmss") + ".pdf";

    PdfWriter writer = new PdfWriter(filename);
    PdfDocument pdf = new PdfDocument(writer);
    Document document = new Document(pdf);

    using (MySqlConnection myConnectionString =
       new MySqlConnection(ConfigurationManager.ConnectionStrings["cn"].ConnectionString))
    {
        using (MySqlCommand cmd =
            new MySqlCommand("SP", myConnectionString))
        {
            cmd.Connection.Open();
            cmd.CommandType = CommandType.StoredProcedure;

            using (MySqlDataAdapter da =
                new MySqlDataAdapter(cmd))
            {
                da.Fill(dt);

                if (dt.Rows.Count > 0)
                {
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        contents = new Paragraph(dt.Rows[i]["contents"].ToString())
                            .SetTextAlignment(TextAlignment.JUSTIFIED)
                            .SetFontSize(12);

                        if (dt.Rows[i]["contents"].ToString().StartsWith("Set") && i != 0)
                        {
                            document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
                            document.Add(new LineSeparator(new DottedLine(1, 2)).SetMarginTop(4));
                        }

                        List<IElement> lst = HtmlConverter.ConvertToElements(dt.Rows[i]["contents"].ToString()).ToList();

                        for (int j = 0; j < lst.Count; j++)
                        {
                            IBlockElement element = (IBlockElement)lst[j];

                            if (dt.Rows[i]["contents"].ToString().StartsWith("Set"))
                            {
                                contents.SetFontSize(12)
                                    .SetBold()
                                    .SetFontColor(ColorConstants.BLUE);
                            }
                            else if (dt.Rows[i]["contents"].ToString().StartsWith("- "))
                            {
                                contents.SetFontSize(10)
                                    .SetBold()
                                    .SetFontColor(ColorConstants.BLACK);
                            }
                            else
                            {
                                contents.SetTextAlignment(TextAlignment.JUSTIFIED_ALL)
                                    .SetFontSize(10)
                                    .SetFontColor(ColorConstants.BLACK);

                            }

                            element.SetProperty(Property.LEADING, new Leading(Leading.MULTIPLIED, -1f));
                            document.Add(element);
                        }
                    }

                    Footer footerHandler = new Footer();
                    pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
                    footerHandler.WriteTotal(pdf);
                    dest = filename.ToString();
                    document.Close();
                }

                Response.Clear();
                Response.ContentType = "application/pdf";
                Response.AppendHeader("Content-Disposition", "attachment; filename=" + dest);
                Response.TransmitFile(dest);
                Response.End();
            }
        }
    }
}

private class TableFooterEventHandler : IEventHandler
{
    private Table table;

    public TableFooterEventHandler(Table table)
    {
        this.table = table;
    }

    public void HandleEvent(Event currentEvent)
    {
        PdfDocumentEvent docEvent = (PdfDocumentEvent)currentEvent;
        PdfDocument pdfDoc = docEvent.GetDocument();
        PdfPage page = docEvent.GetPage();

        int pageNumber = pdfDoc.GetPageNumber(page);
        Rectangle pageSize = page.GetPageSize();

        PdfCanvas canvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);
        new Canvas(canvas, new Rectangle(36, 20, page.GetPageSize().GetWidth() - 72, 50))
            .Add(table)
            .Close();
    }
}

protected class Footer : IEventHandler
{
    protected PdfFormXObject placeholder;
    protected float side = 20;
    protected float x = 300;
    protected float y = 25;
    protected float space = 4.5f;
    protected float descent = 3;

    public Footer()
    {
        placeholder = new PdfFormXObject(new Rectangle(0, 0, side, side));
    }

    public virtual void HandleEvent(Event @event)
    {
        PdfDocumentEvent docEvent = (PdfDocumentEvent)@event;
        PdfDocument pdf = docEvent.GetDocument();
        PdfPage page = docEvent.GetPage();
        int pageNumber = pdf.GetPageNumber(page);
        Rectangle pageSize = page.GetPageSize();

        PdfCanvas pdfCanvas = new PdfCanvas(page);
        Canvas canvas = new Canvas(pdfCanvas, pageSize);
        canvas.SetFontSize(10);

        Paragraph p = new Paragraph()
            .Add("Page ")
            .Add(pageNumber.ToString())
            .Add(" of");

        canvas.ShowTextAligned(p, x, y, TextAlignment.RIGHT);
        canvas.Close();

        pdfCanvas.AddXObjectAt(placeholder, x + space, y - descent);
        pdfCanvas.Release();
    }

    public void WriteTotal(PdfDocument pdfDoc)
    {
        Canvas canvas = new Canvas(placeholder, pdfDoc);
        canvas.SetFontSize(10);
        canvas.ShowTextAligned(pdfDoc.GetNumberOfPages().ToString(),
            0, descent, TextAlignment.LEFT);
        canvas.Close();
    }
}

private class TableHeaderEventHandler : IEventHandler
{
    private Table table;
    private float tableHeight;
    private Document doc;

    public TableHeaderEventHandler(Document doc)
    {
        this.doc = doc;
        InitTable();

        TableRenderer renderer = (TableRenderer)table.CreateRendererSubTree();
        renderer.SetParent(new DocumentRenderer(doc));

        LayoutResult result = renderer.Layout(new LayoutContext(new LayoutArea(0, PageSize.A4)));
        tableHeight = result.GetOccupiedArea().GetBBox().GetHeight();
    }

    public void HandleEvent(Event currentEvent)
    {
        PdfDocumentEvent docEvent = (PdfDocumentEvent)currentEvent;
        PdfDocument pdfDoc = docEvent.GetDocument();
        PdfPage page = docEvent.GetPage();
        int pageNum = docEvent.GetDocument().GetPageNumber(page);
        PdfCanvas canvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);
        PageSize pageSize = pdfDoc.GetDefaultPageSize();
        float coordX = pageSize.GetX() + doc.GetLeftMargin();
        float coordY = pageSize.GetTop() - doc.GetTopMargin();
        float width = pageSize.GetWidth() - doc.GetRightMargin() - doc.GetLeftMargin();
        float height = GetTableHeight();

        Rectangle rect = new Rectangle(coordX, coordY, width, height);

        new Canvas(canvas, rect)
            .Add(table)
            .Close();
    }

    public float GetTableHeight()
    {
        return tableHeight;
    }

    private void InitTable()
    {

    }
}

Answer

I add dotted lines and page numbers to PDF documents using PDFFlow this way:

static void Main(string[] args)
{
    var document = DocumentBuilder.New();
    var section = document.AddSection();

    section
        .SetMargins(30)
        .SetOrientation(PageOrientation.Portrait);

    for(int i = 0; i < 10; i++)
    {
        section
            .AddParagraph(" Here's the dotted line")
            .SetFont(Fonts.Times(15))
            .SetMarginTop(100)
        .ToSection()
            .AddLine()
            .SetWidth(2)
            .SetStroke(Stroke.Dotted)
        .ToSection()
            .InsertPageBreak();
    }

    section
        .AddFooterToBothPages(20)
            .AddParagraph("")
            .SetAlignment(HorizontalAlignment.Right)
            .SetFont(Fonts.Times(15))
                .AddPageNumber("Page ")
            .ToParagraph()
                .AddText(" of 9");

    document.Build("Result.pdf");
}

I also added some styling to the paragraphs in the example to make it more clear. The pages of the resulting pdf file will look like this one: 5-th page

PDFFlow is a cross-platform C# library. It cannot convert from HTML to PDF like iText does. But you might find that the PDFFlow has a more intuitive naming of methods which then allows to generate PDF documents faster and with less amount of code than other tools out there.