Issue with adding Headers to PDF

Aspose Version: 22.2.0
Code: .net

Out current process is as follows:

  1. We Save a Docx as a PDF to a local directory
  2. We load that PDF into a Document
  3. We loop through each page of the document and add different Headers/Footers as needed based on client configuration.
  4. We save the PDF file for access by the customers.

He Header/Footer being saved is primarily in HTML so we use the following code to add them to the pages.

The problem that is occurring during this process is that the text is duplicating in the Header/Footer of the document.

Here is the document being converted to PDF (This document was also created by Aspose)
Document being Converted to PDF.docx (23.8 KB)

Here is the PDF with the Headers/Footers and both duplicate. The header appears twice and the footers appears over the top of each other causing it to look garbled.
PDF with duplication issue.pdf (552.9 KB)

I have tried to adjust the code with varying results, when adjusting and debugging the code I was able to get it to remove the duplication but that is due to the header being adding in the same location multiple times which causes the text to become bold. You can see what I’m referring to below on the 1st page the text looks bold and on the second it appears normal.

Test4.pdf (1.0 MB)

@ST2YKE2 Your question is related to Aspose.PDF. I will move your request into the appropriate forum. my colleagues from Aspose.PDF team will help you shortly.

@ST2YKE2

The issue looks related to somewhere in the code snippet. If possible, can you please share the full code routine of adding header/footer in the PDF? May be you need to initialize the HeaderFooter Class separately for every page in the iteration. If you can please share full code snippet, we will try to replicate the issue in our environment and address it accordingly.

@asad.ali

This is the code that calls our method to add the stampValue for each page in the document. You will see that this calls other methods that ultimately initialize the HeaderFooter class. Don’t pay any attention to the “badpages” portion of the code as we use this when the document has been scanned into the customers system.

for (int i = 1; i <= tempCompiledDoc.Pages.Count; i++)
                {
                    bc.ThrowIfTaskCancelled(bc.CancellationToken);

                    if (badPages.Contains(i))
                    {
                        if (!string.IsNullOrWhiteSpace(pageHeaders[i - 1]))
                        {
                            var stampValue = pageHeaders[i - 1]
                                .Replace("{{document.pagecount}}", (bc.AzureQueueCompileModel.TotalDocumentPageCount + tempCompiledDoc.Pages.Count).ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i == totalAgendaPageCount ? i.ToString() : ""));

                            AddHeaderStamp(tempCompiledDoc, i, stampValue, true);
                        }
                        if (!string.IsNullOrWhiteSpace(pageFooters[i]))
                        {
                            var stampValue = pageFooters[i - 1]
                                .Replace("{{document.pagecount}}", (bc.AzureQueueCompileModel.TotalDocumentPageCount + tempCompiledDoc.Pages.Count).ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i == totalAgendaPageCount ? i.ToString() : ""));

                            AddFooterStamp(tempCompiledDoc, i, stampValue, true);
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrWhiteSpace(pageHeaders[i - 1]))
                        {
                            var stampValue = pageHeaders[i - 1]
                                .Replace("{{document.pagecount}}", tempCompiledDoc.Pages.Count.ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i > totalAgendaPageCount ? i.ToString() : ""));

                            AddHeaderStamp(tempCompiledDoc, i, stampValue);
                        }
                        if (!string.IsNullOrWhiteSpace(pageFooters[i - 1]))
                        {
                            var stampValue = pageFooters[i - 1]
                                .Replace("{{document.pagecount}}", tempCompiledDoc.Pages.Count.ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i > totalAgendaPageCount ? i.ToString() : ""));

                            AddFooterStamp(tempCompiledDoc, i, stampValue);
                        }
                    }
                }

The next methods that get called are

public void AddFooterStamp(Aspose.Pdf.Document compiledDoc, int pageIndex, string value, bool isBadPage = false)
        {
            AddFooter(compiledDoc, pageIndex, value, isBadPage);
        }

        public void AddHeaderStamp(Aspose.Pdf.Document compiledDoc, int pageIndex, string value, bool isBadPage = false)
        {
            AddHeader(compiledDoc, pageIndex, value, isBadPage);
        }

These both call the final methods where the header/footers are added.

private void AddFooter(Aspose.Pdf.Document compiledDoc, int pageIndex, string value, bool isBadPage = false)
        {
            if (isBadPage)
            {
                Aspose.Pdf.Text.Font headerFooterFont = FontRepository.FindFont("Times New Roman");
                float headerFooterFontSize = 10;
                double headerFooterMarginLeft = 90;
                Aspose.Pdf.VerticalAlignment footerVerticalAlignment = Aspose.Pdf.VerticalAlignment.Bottom;
                Aspose.Pdf.HorizontalAlignment headerFooterHorizontalAlignment = Aspose.Pdf.HorizontalAlignment.Right;

                AddStamp(compiledDoc, pageIndex, value, footerVerticalAlignment, headerFooterHorizontalAlignment, headerFooterFont, headerFooterFontSize, headerFooterMarginLeft);
            }
            else
            {
                var page = compiledDoc.Pages[pageIndex];
                page.Footer = new Aspose.Pdf.HeaderFooter();

                if (CustomerConfig.For(bc.CustomerCallContext).PdfMarginRight != null)
                    page.Footer.Margin.Right = int.Parse(CustomerConfig.For(bc.CustomerCallContext).PdfMarginRight);
                else
                    page.Footer.Margin.Right = 50;

                if (CustomerConfig.For(bc.CustomerCallContext).PdfMarginLeft != null)
                    page.Footer.Margin.Left = int.Parse(CustomerConfig.For(bc.CustomerCallContext).PdfMarginLeft);
                else
                    page.Footer.Margin.Left = 50;

                page.Footer.Paragraphs.Add(new Aspose.Pdf.HtmlFragment(value));
            }
        }

        private void AddHeader(Aspose.Pdf.Document compiledDoc, int pageIndex, string value, bool isBadPage = false)
        {
            if (isBadPage)
            {
                Aspose.Pdf.Text.Font headerFooterFont = FontRepository.FindFont("Times New Roman");
                float headerFooterFontSize = 10;
                double headerFooterMarginLeft = 90;
                Aspose.Pdf.HorizontalAlignment headerFooterHorizontalAlignment = Aspose.Pdf.HorizontalAlignment.Right;
                Aspose.Pdf.VerticalAlignment headerVerticalAlignment = Aspose.Pdf.VerticalAlignment.Top;

                AddStamp(compiledDoc, pageIndex, value, headerVerticalAlignment, headerFooterHorizontalAlignment, headerFooterFont, headerFooterFontSize, headerFooterMarginLeft);
            }
            else
            {
                var page = compiledDoc.Pages[pageIndex];
                page.Header = new Aspose.Pdf.HeaderFooter();

                if (CustomerConfig.For(bc.CustomerCallContext).PdfMarginRight != null)
                    page.Header.Margin.Right = int.Parse(CustomerConfig.For(bc.CustomerCallContext).PdfMarginRight);
                else
                    page.Header.Margin.Right = 50;

                if (CustomerConfig.For(bc.CustomerCallContext).PdfMarginLeft != null)
                    page.Header.Margin.Left = int.Parse(CustomerConfig.For(bc.CustomerCallContext).PdfMarginLeft);
                else
                    page.Header.Margin.Left = 50;

                page.Header.Paragraphs.Add(new Aspose.Pdf.HtmlFragment(value));
            }
        }

@ST2YKE2

We are checking it and will get back to you shortly.

1 Like

@asad.ali any updates on this issue?

@ST2YKE2

We have been trying to execute the code snippet that you shared with us. You are using a method i.e. AddStamp(compiledDoc, pageIndex, value, headerVerticalAlignment, headerFooterHorizontalAlignment, headerFooterFont, headerFooterFontSize, headerFooterMarginLeft); which is missing in your code. Could that may be the culprit for duplicate header footer? Anyways, can you please share complete definition of this method as well?

The AddStamp never gets called but here is the code for you.

private void AddStamp(Aspose.Pdf.Document compiledDoc, int pageIndex, string value, Aspose.Pdf.VerticalAlignment verticalAlignment, Aspose.Pdf.HorizontalAlignment horizontalAlignment, Aspose.Pdf.Text.Font headerFooterFont, float headerFooterFontSize, double headerFooterMarginLeft)
        {
            var formattedValue = System.Text.RegularExpressions.Regex.Replace(value, "<.*?>", string.Empty);

            FormattedText text = new FormattedText();

            foreach (var item in formattedValue.Split('\n').Where(x => !string.IsNullOrEmpty(x.Trim())))
            {
                text.AddNewLineText(item + "\t\t\t\t\t\t\t\t\t\t\t\t");
            }

            text.AddNewLineText(Environment.NewLine);

            var ts = new Aspose.Pdf.TextStamp(text)
            {
                TopMargin = 10,
                WordWrap = true,
                Scale = false,
                Width = compiledDoc.Pages[pageIndex].PageInfo.Width,
                VerticalAlignment = verticalAlignment,
                HorizontalAlignment = horizontalAlignment,
                LeftMargin = compiledDoc.Pages[pageIndex].PageInfo.Width - headerFooterMarginLeft
            };
            ts.TextState.Font = headerFooterFont;
            ts.TextState.FontSize = headerFooterFontSize;

            compiledDoc.Pages[pageIndex].AddStamp(ts);
        }

@ST2YKE2

Thanks for your patience. We have simplified the code snippet and modified your existing approach to add header footer in the PDF pages like below:

public static void AddHeaderFooterInPDF(string dataDir)
{
    Document doc = new Document();
    doc.Pages.Add();
    doc.Pages.Add();
    AddHeaderStamp(doc.Pages[1], "Test Header 1");
    AddFooterStamp(doc.Pages[1], "Test Footer 1");
    AddHeaderStamp(doc.Pages[2], "Test Header 2");
    AddFooterStamp(doc.Pages[2], "Test Footer 2");
    doc.Save(dataDir + "headerfooter.pdf");
}

public static void AddFooterStamp(Page page, string value, bool isBadPage = false)
{
    AddFooter(page, value, isBadPage);
}

public static void AddHeaderStamp(Page page, string value, bool isBadPage = false)
{
    AddHeader(page, value, isBadPage);
}

private static void AddFooter(Page page, string value, bool isBadPage = false)
{
    page.Footer = new Aspose.Pdf.HeaderFooter();

    page.Footer.Margin.Right = 50;
    page.Footer.Margin.Left = 50;

    page.Footer.Paragraphs.Add(new Aspose.Pdf.HtmlFragment(value));
}

private static void AddHeader(Page page, string value, bool isBadPage = false)
{
    page.Header = new Aspose.Pdf.HeaderFooter();

    page.Header.Margin.Right = 50;
    page.Header.Margin.Left = 50;

    page.Header.Paragraphs.Add(new Aspose.Pdf.HtmlFragment(value));
}

Using above code snippet, we could not notice the issue that you described. Instead of passing the whole document, you can simply pass the page object to the methods responsible for adding header/footer. An output generated by the above code snippet has also been attached for your kind reference. Would you please give this code snippet a try in your environment and share your feedback with us.
headerfooter.pdf (81.7 KB)

@asad.ali
I changed the code to follow your recommendation and we are just passing the single page into the methods now and it is still coming at as follows with the header and footer duplicated.

Packet_20231130202820244.pdf (555.7 KB)

for (int i = 1; i <= tempCompiledDoc.Pages.Count; i++)
                {
                    bc.ThrowIfTaskCancelled(bc.CancellationToken);

                    if (badPages.Contains(i))
                    {
                        if (!string.IsNullOrWhiteSpace(pageHeaders[i - 1]))
                        {
                            var stampValue = pageHeaders[i - 1]
                                .Replace("{{document.pagecount}}", (bc.AzureQueueCompileModel.TotalDocumentPageCount + tempCompiledDoc.Pages.Count).ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i == totalAgendaPageCount ? i.ToString() : ""));

                            AddHeaderStamp(tempCompiledDoc.Pages[i], stampValue, true);
                        }
                        if (!string.IsNullOrWhiteSpace(pageFooters[i]))
                        {
                            var stampValue = pageFooters[i - 1]
                                .Replace("{{document.pagecount}}", (bc.AzureQueueCompileModel.TotalDocumentPageCount + tempCompiledDoc.Pages.Count).ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i == totalAgendaPageCount ? i.ToString() : ""));

                            AddFooterStamp(tempCompiledDoc.Pages[i], stampValue, true);
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrWhiteSpace(pageHeaders[i - 1]))
                        {
                            var stampValue = pageHeaders[i - 1]
                                .Replace("{{document.pagecount}}", tempCompiledDoc.Pages.Count.ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i > totalAgendaPageCount ? i.ToString() : ""));

                            AddHeaderStamp(tempCompiledDoc.Pages[i], stampValue);
                        }
                        if (!string.IsNullOrWhiteSpace(pageFooters[i - 1]))
                        {
                            var stampValue = pageFooters[i - 1]
                                .Replace("{{document.pagecount}}", tempCompiledDoc.Pages.Count.ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i > totalAgendaPageCount ? i.ToString() : ""));

                            AddFooterStamp(tempCompiledDoc.Pages[i], stampValue);
                        }
                    }
                }

which calls the following 1 of the following

public void AddFooterStamp(Aspose.Pdf.Page page, string value, bool isBadPage = false)
        {
            AddFooter(page, value, isBadPage);
        }

        public void AddHeaderStamp(Aspose.Pdf.Page page, string value, bool isBadPage = false)
        {
            AddHeader(page, value, isBadPage);
        }

        private void AddFooter(Aspose.Pdf.Page page, string value, bool isBadPage = false)
        {
            if (isBadPage)
            {
                Aspose.Pdf.Text.Font headerFooterFont = FontRepository.FindFont("Times New Roman");
                float headerFooterFontSize = 10;
                double headerFooterMarginLeft = 90;
                Aspose.Pdf.VerticalAlignment footerVerticalAlignment = Aspose.Pdf.VerticalAlignment.Bottom;
                Aspose.Pdf.HorizontalAlignment headerFooterHorizontalAlignment = Aspose.Pdf.HorizontalAlignment.Right;

                AddStamp(page, value, footerVerticalAlignment, headerFooterHorizontalAlignment, headerFooterFont, headerFooterFontSize, headerFooterMarginLeft);
            }
            else
            {
                page.Footer = new Aspose.Pdf.HeaderFooter();

                if (CustomerConfig.For(bc.CustomerCallContext).PdfMarginRight != null)
                    page.Footer.Margin.Right = int.Parse(CustomerConfig.For(bc.CustomerCallContext).PdfMarginRight);
                else
                    page.Footer.Margin.Right = 50;

                if (CustomerConfig.For(bc.CustomerCallContext).PdfMarginLeft != null)
                    page.Footer.Margin.Left = int.Parse(CustomerConfig.For(bc.CustomerCallContext).PdfMarginLeft);
                else
                    page.Footer.Margin.Left = 50;

                page.Footer.Paragraphs.Add(new Aspose.Pdf.HtmlFragment(value));
            }
        }

        private void AddHeader(Aspose.Pdf.Page page, string value, bool isBadPage = false)
        {
            if (isBadPage)
            {
                Aspose.Pdf.Text.Font headerFooterFont = FontRepository.FindFont("Times New Roman");
                float headerFooterFontSize = 10;
                double headerFooterMarginLeft = 90;
                Aspose.Pdf.HorizontalAlignment headerFooterHorizontalAlignment = Aspose.Pdf.HorizontalAlignment.Right;
                Aspose.Pdf.VerticalAlignment headerVerticalAlignment = Aspose.Pdf.VerticalAlignment.Top;

                AddStamp(page, value, headerVerticalAlignment, headerFooterHorizontalAlignment, headerFooterFont, headerFooterFontSize, headerFooterMarginLeft);
            }
            else
            {
                //var page = compiledDoc.Pages[pageIndex];
                page.Header = new Aspose.Pdf.HeaderFooter();

                if (CustomerConfig.For(bc.CustomerCallContext).PdfMarginRight != null)
                    page.Header.Margin.Right = int.Parse(CustomerConfig.For(bc.CustomerCallContext).PdfMarginRight);
                else
                    page.Header.Margin.Right = 50;

                if (CustomerConfig.For(bc.CustomerCallContext).PdfMarginLeft != null)
                    page.Header.Margin.Left = int.Parse(CustomerConfig.For(bc.CustomerCallContext).PdfMarginLeft);
                else
                    page.Header.Margin.Left = 50;

                page.Header.Paragraphs.Add(new Aspose.Pdf.HtmlFragment(value));
            }
        }

        private void AddStamp(Aspose.Pdf.Page page, string value, Aspose.Pdf.VerticalAlignment verticalAlignment, Aspose.Pdf.HorizontalAlignment horizontalAlignment, Aspose.Pdf.Text.Font headerFooterFont, float headerFooterFontSize, double headerFooterMarginLeft)
        {
            var formattedValue = System.Text.RegularExpressions.Regex.Replace(value, "<.*?>", string.Empty);

            FormattedText text = new FormattedText();

            foreach (var item in formattedValue.Split('\n').Where(x => !string.IsNullOrEmpty(x.Trim())))
            {
                text.AddNewLineText(item + "\t\t\t\t\t\t\t\t\t\t\t\t");
            }

            text.AddNewLineText(Environment.NewLine);

            var ts = new Aspose.Pdf.TextStamp(text)
            {
                TopMargin = 10,
                WordWrap = true,
                Scale = false,
                Width = page.PageInfo.Width,
                VerticalAlignment = verticalAlignment,
                HorizontalAlignment = horizontalAlignment,
                LeftMargin = page.PageInfo.Width - headerFooterMarginLeft
            };
            ts.TextState.Font = headerFooterFont;
            ts.TextState.FontSize = headerFooterFontSize;

            page.AddStamp(ts);
        }

You will notice I am not passing in the page each time instead of the entire document. It is duplicating the footer and the header each time regardless.

I don’t know if it is important to mention again but this PDF is being generated by a docx that is being coverted to PDF using aspose. Is there a setting when adding the headers/footers that tells the system to have each page the same?

I also noticed in your code you are creating a PDF using aspose Document.

Here is our entire code that generates the PDF and you will notice is is an already existing DOCX

public async Task ShouldCreatePDFFromDocxCompile(string permFilePath, CompileMeetingContentModel data, CompiledMeetingDocument compiledMeetingDoc = null)
        {
            if (bc.AutoCreatePdfFromDocxSetting != true)
            {
                return;
            }

            DateTime? created = DateTime.UtcNow;

            if (data == null)
            {
                data = await bc.GetMeetingData(compiledMeetingDoc);
                await bc.CompileUpdates.SendCompileUpdates(
                    bc.AzureQueueCompileModel,
                    CompileEvents.Updated,
                    new int[1] { 1 },
                    null
                );
            }

            var compiledDoc = await bc.StartCompile(data.Meeting.Id, data.MeetingTemplate.Id, new List<CompileOutputTypes>() { CompileOutputTypes.Pdf }, created);
            compiledDoc.MeetingTemplateId = data.MeetingTemplate?.Id ?? null;

            var file = compiledDoc.CompiledMeetingDocumentFiles.FirstOrDefault(x => x.CompileOutputType == CompileOutputTypes.Pdf);
            file.PublishStatus = PublishStatuses.Unpublish;
            file.Language = Localizer_i18n.CurrentLanguage.Value;

            Aspose.Words.Saving.PdfSaveOptions pdfSaveOptions = new Aspose.Words.Saving.PdfSaveOptions();
            pdfSaveOptions.Compliance = Aspose.Words.Saving.PdfCompliance.PdfA2a;

            string fileName = string.Format("{0}_{1}", HelperLogic.CleanFilename(data.MeetingTemplate.Name), compiledDoc.Created.ToString("yyyyMMddHHmmssFFF"));
            var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "temp", $"{data.Meeting.Id}", $"{fileName}.pdf");

            var docxDocument = new Document(bc.AzureProvider.DownloadToStream(permFilePath));
            ELSLogHelper.InsertInfoLog(ELSLogHelper.AsposeLogMessage("Load"), MethodBase.GetCurrentMethod()?.Name, MethodBase.GetCurrentMethod().DeclaringType?.Name, Environment.StackTrace);

            docxDocument.Save(filePath, pdfSaveOptions);
            ELSLogHelper.InsertInfoLog(ELSLogHelper.AsposeLogMessage("Save"), MethodBase.GetCurrentMethod()?.Name, MethodBase.GetCurrentMethod().DeclaringType?.Name, Environment.StackTrace);

            bool meetingTemplateIncludeDocuments = data.MeetingTemplate.IncludeSystemDocuments || data.MeetingTemplate.IncludeAttachments;
            bool compileServiceIsAvailable = await bc.BaseSettings.GetCompileServiceFeatureFlag();
            bool compileOutputTypeIsPdf = file.CompileOutputType == CompileOutputTypes.Pdf;
            List<int> badPages = new List<int>();
            var pageHeaders = new List<string>();
            var pageFooters = new List<string>();

            if (meetingTemplateIncludeDocuments)
            {
                var meetingTitle = data.Meeting.Title;

                Aspose.Pdf.Document tempCompiledDoc;

                using (var pdfStream = File.Open(filePath, FileMode.Open))
                {
                    tempCompiledDoc = new Aspose.Pdf.Document(pdfStream);
                }

                var totalAgendaPageCount = tempCompiledDoc.Pages.Count;
                var agHeaderFormat = data.MeetingTypeTemplate.CompileAgendaPageHeader;
                var agFooterFormat = data.MeetingTypeTemplate.CompileAgendaPageFooter;

                string location = data.Meeting.Location;
                List<string> nextMeeting = await bc.MeetingLogic.NextbyDatetime(data.Meeting.Id, data.Meeting.MeetingTypeId, data.Meeting.ScheduledEvent.Start);
                var templateName = data.MeetingTypeTemplate.Name;

                var nextDate = "";
                var nextTime = "";
                var nextLocation = "";
                string itemTitle = data.MeetingTypeTemplate.Name;

                if (nextMeeting != null && nextMeeting.Count > 0)
                {
                    nextDate = nextMeeting[0];
                    nextTime = nextMeeting[1];
                    nextLocation = nextMeeting[2];
                }

                //This is for page headers and footers on the Agenda only.
                for (int i = 0; i < tempCompiledDoc.Pages.Count; i++)
                {
                    bc.ThrowIfTaskCancelled(bc.CancellationToken);

                    var headerFormatValue = new HeaderFooterFormatValue(agHeaderFormat, meetingTitle, itemTitle, nextDate, nextTime, location, nextLocation)
                    {
                        AgendaPageNumber = (i + 1).ToString(),
                        AgendaPageCount = tempCompiledDoc.Pages.Count.ToString(),
                        TemplateName = templateName,
                        MeetingDatetime = DateTimeLogic.GetLocalTime(bc.CustomerCallContext.TimeZone, data.Meeting.ScheduledEvent.Start).ToString(),
                        MeetingLocation = location,
                        CompileDatetime = DateTimeLogic.GetLocalTime(bc.CustomerCallContext.TimeZone, Convert.ToDateTime(created)).ToString(),
                        MeetingCustomTrackingNumber = data.Meeting.CustomTrackingNumber,
                        Committee = data.Meeting.MeetingType.Committee.Name,
                        NextDate = nextDate,
                        NextTime = nextTime,
                        NextLocation = nextLocation
                    };

                    pageHeaders.Add(bc.ReplaceHeaderFooterFormatValues(headerFormatValue));

                    var footerFormatValue = new HeaderFooterFormatValue(agFooterFormat, meetingTitle, itemTitle, nextDate, nextTime, location, nextLocation)
                    {
                        AgendaPageNumber = (i + 1).ToString(),
                        AgendaPageCount = tempCompiledDoc.Pages.Count.ToString(),
                        TemplateName = templateName,
                        MeetingDatetime = DateTimeLogic.GetLocalTime(bc.CustomerCallContext.TimeZone, data.Meeting.ScheduledEvent.Start).ToString(),
                        MeetingLocation = location,
                        CompileDatetime = DateTimeLogic.GetLocalTime(bc.CustomerCallContext.TimeZone, Convert.ToDateTime(created)).ToString(),
                        MeetingCustomTrackingNumber = data.Meeting.CustomTrackingNumber,
                        Committee = data.Meeting.MeetingType.Committee.Name,
                        NextDate = nextDate,
                        NextTime = nextTime,
                        NextLocation = nextLocation
                    };

                    pageFooters.Add(bc.ReplaceHeaderFooterFormatValues(footerFormatValue));
                }

                await IncludeAttachmentsUsingAspose(data, tempCompiledDoc, pageHeaders, pageFooters, meetingTitle, Convert.ToDateTime(created), badPages);

                for (int i = 1; i <= tempCompiledDoc.Pages.Count; i++)
                {
                    bc.ThrowIfTaskCancelled(bc.CancellationToken);

                    if (badPages.Contains(i))
                    {
                        if (!string.IsNullOrWhiteSpace(pageHeaders[i - 1]))
                        {
                            var stampValue = pageHeaders[i - 1]
                                .Replace("{{document.pagecount}}", (bc.AzureQueueCompileModel.TotalDocumentPageCount + tempCompiledDoc.Pages.Count).ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i == totalAgendaPageCount ? i.ToString() : ""));

                            AddHeaderStamp(tempCompiledDoc.Pages[i], stampValue, true);
                        }
                        if (!string.IsNullOrWhiteSpace(pageFooters[i]))
                        {
                            var stampValue = pageFooters[i - 1]
                                .Replace("{{document.pagecount}}", (bc.AzureQueueCompileModel.TotalDocumentPageCount + tempCompiledDoc.Pages.Count).ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i == totalAgendaPageCount ? i.ToString() : ""));

                            AddFooterStamp(tempCompiledDoc.Pages[i], stampValue, true);
                        }
                    }
                    else
                    {
                        if (!string.IsNullOrWhiteSpace(pageHeaders[i - 1]))
                        {
                            var stampValue = pageHeaders[i - 1]
                                .Replace("{{document.pagecount}}", tempCompiledDoc.Pages.Count.ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i > totalAgendaPageCount ? i.ToString() : ""));

                            AddHeaderStamp(tempCompiledDoc.Pages[i], stampValue);
                        }
                        if (!string.IsNullOrWhiteSpace(pageFooters[i - 1]))
                        {
                            var stampValue = pageFooters[i - 1]
                                .Replace("{{document.pagecount}}", tempCompiledDoc.Pages.Count.ToString())
                                .Replace("{{document.pagenumber}}", (i).ToString())
                                .Replace("{{document.pagecountafteragenda}}", bc.AzureQueueCompileModel.TotalDocumentPageCount.ToString())
                                .Replace("{{document.pagenumberafteragenda}}", (i > totalAgendaPageCount ? i.ToString() : ""));

                            AddFooterStamp(tempCompiledDoc.Pages[i], stampValue);
                        }
                    }
                }

                await SavePdfFile(file, fileName, data.Meeting.Id, false, tempCompiledDoc);

                tempCompiledDoc.FreeMemory();
                tempCompiledDoc.Dispose();
                tempCompiledDoc = null;
            }
            else
            {
                file.FilePath = string.Format("Meetings/{0}/{1}{2}", data.Meeting.Id, fileName, ".pdf");
                file.CompileFinishedDate = DateTime.UtcNow;

                await bc.AzureProvider.SaveAzureFileAsync(file.FilePath, File.ReadAllBytes(filePath));
            }

            await bc.CustomerCallContext.SystemContext.UpdateFileAsync(file);

            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            docxDocument = null;

            bc.ThrowIfTaskCancelled(bc.CancellationToken);
            await bc.SaveCompile(compiledDoc);

            GC.Collect();
        }

@ST2YKE2

We are checking it and will get back to you shortly.

@asad.ali
Any update on this issue? I found also that if I add the header to the pages, then create a brand new PDF Document and add the page with the header to the new PDF document it does not duplicate the heading any longer. I really don’t think I should need to perform this type of a workaround and also when you are dealing with PDF’s (which we do) that are thousands of pages it can be very problematic for memory consumption.

@ST2YKE2

It may also be possible that Header/Footer are being duplicated because they are present in the DOCX file as well from which you are generating PDF. OR during the process of conversion, they are being added. Nevertheless, we have sample DOCX file already. Can you please share the PDF file that you obtained from DOCX in your environment. Please share it before adding header/footer. We will use it in our environment and share our feedback with you.

@asad.ali
Here is the document created from the Docx before headers and footers are added to it.
PDF From DOCX Before Headers and Footers.pdf (125.9 KB)

@ST2YKE2

We again tested using the below simplified code snippet and could not replicate the issue. Please check the attached PDF document for your kind reference:

public static void AddHeaderFooterInPDF(string dataDir)
{
    Document doc = new Document(dataDir + "PDF From DOCX Before Headers and Footers.pdf");
    AddHeaderStamp(doc.Pages[1], "Test Header 1");
    AddFooterStamp(doc.Pages[1], "Test Footer 1");
    AddHeaderStamp(doc.Pages[2], "Test Header 2");
    AddFooterStamp(doc.Pages[2], "Test Footer 2");
    doc.Save(dataDir + "headerfooter.pdf");
}

public static void AddFooterStamp(Page page, string value, bool isBadPage = false)
{
    AddFooter(page, value, isBadPage);
}

public static void AddHeaderStamp(Page page, string value, bool isBadPage = false)
{
    AddHeader(page, value, isBadPage);
}

private static void AddFooter(Page page, string value, bool isBadPage = false)
{
    page.Footer = new Aspose.Pdf.HeaderFooter();

    page.Footer.Margin.Right = 50;
    page.Footer.Margin.Left = 50;

    page.Footer.Paragraphs.Add(new Aspose.Pdf.HtmlFragment(value));
}

private static void AddHeader(Page page, string value, bool isBadPage = false)
{
    page.Header = new Aspose.Pdf.HeaderFooter();

    page.Header.Margin.Right = 50;
    page.Header.Margin.Left = 50;

    page.Header.Paragraphs.Add(new Aspose.Pdf.HtmlFragment(value));
}

headerfooter.pdf (208.1 KB)