poveda
poveda

Reputation: 33

Itextsharp Insert footer on end of the page

I have a template split into 3 files(header, body and footer), all of them in html. I need to export a pdf file using

itextsharp lib.

I use the folowing code to do that.

Function to export the file

public string GeneratePDF(Dictionary<string, object> fieldValues, string pdfPath, string templatePath)
        {
            //Inicializes a New Document
            Document document = new Document(PageSize.A4,0,0,0,0);

            try
            {
                PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(pdfPath, FileMode.Create));                 
                PdfPageEvents events = new PdfPageEvents();
                //Initializes page events
                writer.PageEvent = events;
                //Open Document
                document.Open();

                //Gerar efetivamente o html
                TemplateHelper objTemplate = new TemplateHelper();
                //This function is not important, only replaces the content by a dictionary
                string htmlContent = objTemplate.GenerateHTML(fieldValues, templatePath);

                //Gerar o PD
                StringReader reader = new StringReader(htmlContent);
                XMLWorkerHelper.GetInstance().ParseXHtml(writer, document, reader);
            }
            catch (Exception ex)
            {
                throw;
            }
            finally
            {
                document.Close(); 
            }

            return pdfPath;
        }

and the page events

public class PdfPageEvents : PdfPageEventHelper
{
    public override void OnStartPage(PdfWriter writer, Document document)
    {
            StreamReader template = new StreamReader(@"d:\Header.html");
            string htmlContent = template.ReadToEnd();
            StringReader reader = new StringReader(htmlContent);

            ElementList e = XMLWorkerHelper.ParseToElementList(htmlContent, "");
            PdfDiv div = (PdfDiv)e.First();
            document.Add(div.Content.First());
            template.Close();

        template = new StreamReader(@"d:\Footer.html");
        htmlContent = template.ReadToEnd();
        reader = new StringReader(htmlContent);

    }
    //começa com o cabeçalho
    public override void OnEndPage(PdfWriter writer, Document document)
    {
        StreamReader template = new StreamReader(@"d:\Footer.html");
        string htmlContent = template.ReadToEnd();
        StringReader reader = new StringReader(htmlContent);
        ElementList elementListFooter = XMLWorkerHelper.ParseToElementList(htmlContent, "");
        PdfDiv div = (PdfDiv)elementListFooter.First();
        PdfPTable t = (PdfPTable)div.Content.First();

        document.Add(t);
        template.Close();
    }
}

When I export to pdf, the header works fine, but the footer don't work. I tried to put the footer content on the footer of

the document, but unsuccessfully. If the content of the body is to large to fit in one page, the footer content is set

below the header and below the content on the last page. The follow image illustrates this problem.

PDF with one page. The footer is below of the content, but not positioned on the bottom of the page

Footer on the top of the first page and before body content

enter image description here

Upvotes: 1

Views: 4110

Answers (1)

Chris Haas
Chris Haas

Reputation: 55457

To explain what Bruno is saying in the comments in a little more detail, if you Add() content in a page event, you could conceivably cause the document to generate a new page which would cause your page event to fire again. Even more fun, if your page event added too much content you could actually run into an infinite loop of add, overflow, new page, repeat.

If you want a true header and footer, set your Document margins to account for the heights of both and normal Document.Add() code will respect it. If you don't know how tall your header and/or footer is going to be each time you can try using this code to calculate the height.

Then you can use page events or two-pass to just add your header and footer and known fixed locations using DirectContent or ColumnText. Your content seems rather simple so you could probably convert it to just normal iTextSharp commands but if you want to stay in HTML for your header and footer see this post for parsing HTML to an element list and adding that to a ColumnText.

Upvotes: 1

Related Questions