Use iTextSharp footer, add horizontal line

 //font
           Font font = new Font(BaseFont.CreateFont("font file path", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED), 24, Font.BOLD));
           
           Document document = new Document(PageSize. A4);
           document.SetMargins(55, 55, 38, 70);//Margin settings: left, right, top, bottom

            PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("Full path and name of the generated PDF file", FileMode.Create));
            SetFooter(writer);//Set footer (including header)
            
            document. Open();
            // Initialize header form
            PdfPTable headTable = new PdfPTable(2)
            {
                HorizontalAlignment = (Element.ALIGN_CENTER),
                WidthPercentage = (100)
            };
            headTable. SetWidths(new int[] { 55, 45 });
            headTable.SpacingBefore = (20);
            
            // title name
            string title = "Title of PDF";
            Chunk formChunk = new Chunk(title, font);
            PdfPCell formCell = new PdfPCell(new Phrase(formChunk));
            formCell.HorizontalAlignment = (Element.ALIGN_CENTER);
            formCell. Border = (0);
            formCell. Colspan = (2);
            headTable.AddCell(formCell);
            // add header form
            document.Add(headTable);

            PdfPTable blxxTab = CreateBlxxPdfTable();
            document.Add(blxxTab);
           
            // occupied height
            float topHeight = headTable.TotalHeight + blxxTab.TotalHeight;
            int pageCount = writer. PageNumber;
            document. Close();
    
    //Main content
    private PdfPTable CreateBlxxPdfTable()
     {
        PdfPTable blxxTab = new PdfPTable(42);
        blxxTab.HorizontalAlignment = (Element.ALIGN_CENTER);
        blxxTab. WidthPercentage = (100);
        blxxTab.SetWidths(new int[] { 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12 , 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 14, 15 });
        blxxTab.SpacingBefore = (20);

        //time
        PdfPCell Lable = PdfPrintUtil.GetTableCell("Time", font, 0, qdTableRowMiniHeight);
        Lable. BorderWidth = (1);
        Lable.HorizontalAlignment = (Element.ALIGN_LEFT);
        Lable.Border = (Rectangle.LEFT_BORDER); ;
        Lable.DisableBorderSide(Rectangle.LEFT_BORDER);
        Lable. Colspan = (3);
        blxxTab. AddCell(Lable);

        PdfPCell time = PdfPrintUtil.GetTableCell(DateTime.Now.ToString(), font, 0, qdTableRowMiniHeight);
        time. Colspan = (39);
        time. Border = (Rectangle. BOTTOM_BORDER);
        blxxTab. AddCell(time);
        return blxxTab;
    }

    /// <summary>
    /// Set the footer
    /// </summary>
    /// <param name="writer"></param>
    private void SetFooter(PdfWriter writer)
    {
        PdfHeaderFooter headerFooter = new PdfHeaderFooter();
        writer.SetBoxSize("art", PageSize.A4);
        writer.PageEvent = headerFooter;
    }


using iTextSharp.text;
using iTextSharp.text.pdf;
using System;
using System.Collections.Generic;
using System.IO;
using System. Linq;
using System. Text;
public class PdfHeaderFooter : PdfPageEventHelper
{
    /**
* header
*/
    public String header = "";

    /**
     * The font size of the document, the footer header should preferably be the same size as the text
     */
    public int presentFontSize = 15;

    /**
     * Document page size, it is best to pass it in front, otherwise the default is A4 paper
     */
    public Rectangle pageSize = PageSize.A4;

    // template
    public PdfTemplate total;

    // base font object
    public BaseFont bf = null;

    // The font object generated by using the basic font is generally used to generate Chinese text
    public Font fontDetail = null;

    /**
     *
     * Creates a new instance of PdfReportM1HeaderFooter No parameter construction method.
     *
     */
    public PdfReportM1HeaderFooter()
    {

    }

    /**
     *
     * Creates a new instance of PdfReportM1HeaderFooter construction method.
     *
     * @param yeMei
     * header string
     * @param presentFontSize
     * Data body font size
     * @param pageSize
     * Rectangle objects such as page document size, A4, A5, A6 horizontal flipping, etc.
     */
    public PdfReportM1HeaderFooter(String yeMei, int presentFontSize, Rectangle pageSize)
    {
        this.header = yeMei;
        this.presentFontSize = presentFontSize;
        this.pageSize = pageSize;
    }

    public void setHeader(String header)
    {
        this. header = header;
    }

    public void SetPresentFontSize(int presentFontSize)
    {
        this.presentFontSize = presentFontSize;
    }

    /**
     *
     * TODO create template when document is opened
     *
     * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
     */
    public override void OnOpenDocument(PdfWriter writer, Document document)
    {
        total = writer.DirectContent.CreateTemplate(50, 50);//The length, width and height of the rectangle in total pages
    }

    /**
     *
     * TODO When closing each page, write
     *
     * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
     */
    public override void OnEndPage(PdfWriter writer, Document document)
    {
        float y = 20;
        
        if (bf == null)
        {
            bf = new Font(BaseFont.CreateFont("font file path", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED), 24, Font.BOLD));
        }
        if (fontDetail == null)
        {
            fontDetail = new Font(BaseFont.CreateFont("font file path", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED), 24, Font.BOLD));
        }
       
        // 1. Write header
        ColumnText.ShowTextAligned(writer.DirectContent, Element.ALIGN_LEFT, new Phrase(header, fontDetail), document.Left, document.Top + 20, 0);

        // 2. Write to page X/total
        int pageS = writer. PageNumber;
        String foot3 = "The first " + pageS + " page total";
        Phrase footer3 = new Phrase(foot3, fontDetail);

        // 3. Calculate the length of foot1 in the first half, and then locate the x-axis coordinates of the words 'Y page' in the last part, and the font length should also be calculated = len
        float len = bf. GetWidthPoint(foot3, presentFontSize);

        // 4. Get the current PdfContentByte
        PdfContentByte cb = writer. DirectContent;
       //Add horizontal lines up and down
        var line = new iTextSharp.text.pdf.draw.LineSeparator(1F, (document.Right - document.LeftMargin) * -1, Color.BLACK, Element.ALIGN_LEFT, 7F);
        if (pageS > 1)
        {
            line = new iTextSharp.text.pdf.draw.LineSeparator(1F, (document.Right - document.LeftMargin) * -1, Color.BLACK, Element.ALIGN_LEFT, 7.5F);

            var lineTop = new iTextSharp.text.pdf.draw.LineSeparator(1.5F, (document.Right - document.LeftMargin) * -1, Color.BLACK, Element.ALIGN_LEFT, 0F);
            Paragraph pTop = new Paragraph(new Chunk(lineTop));
            ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, pTop, document.LeftMargin, document.Top, 0);//First horizontal line
        }
        Paragraph p = new Paragraph(new Chunk(line));
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, p, document.LeftMargin, document.BottomMargin, 0);//footer horizontal line

        // 5. Write in footer 1, the x-axis is (right margin + left margin + right() -left()- len)/2.0F and offset 20F to suit human visual experience, otherwise it will look too biased to the naked eye On the left, the y-axis is the bottom boundary -20, otherwise the border will overlap into the data body and it will not be the footer; note that the Y-axis is accumulated from bottom to top, and the Top value at the top is hundreds of times larger than Bottom of.
        ColumnText.ShowTextAligned(cb, Element.ALIGN_LEFT, footer3, document.Right - 165 + document.LeftMargin, y, 0);

        // 6. Add the template written in footer 2 (that is, the word Y page of the footer) to the document, and calculate the sum of the template and the Y axis, X=(right border-left border-len value of the first half)/ 2.0F + len , the y axis remains the same as before, and the bottom boundary is -20
        cb.AddTemplate(total, document.Right - 165 + document.LeftMargin + len, y); // adjust the display position of the template
        if (pageS > 0)
        {
                QrCodePath = Path.Combine(HTKApp.RunFolder, AppPath.TmpDir, $"{HTKApp.RandomSn}.png");
                MakeQrCode.GetBlBarCodeFilePath(QrCodePath, Bllx, BlxxId, pageS, 150, 150);
                if (File. Exists(QrCodePath))
                {
                    try
                    {
                        Image image = Image. GetInstance(QrCodePath);
                        image. SetDpi(1000, 1000);
                        image.ScaleToFit(65, 65);
                        image. SetAbsolutePosition(490f, 25f);
                        cb.AddImage(image);
                    }
                    catch (Exception)
                    {

                    }
                }
            }
        
    }

    /**
     *
     * TODO When closing the document, replace the template and complete the entire header and footer components
     *
     * @see com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
     */
    public override void OnCloseDocument(PdfWriter writer, Document document)
    {
        // 7. The last step is to replace the template with the actual Y value when closing the document. So far, the page x of y has been made, which is perfectly compatible with various document sizes.
        total. BeginText();
        total.SetFontAndSize(bf, presentFontSize);// The font and color of the generated template
        String foot2 = " " + (writer. PageNumber - 1) + "page";
        total.ShowText(foot2);// The content displayed by the template
        total. EndText();
        total. ClosePath();
    }
}