Preserve existing user headers

I have a requirement to apply some text into the header of a Word document. The initial implementation works great as we took the approach of removing all headers and then adding our our own. We reapply the header with each save which this approach also supports:

Document doc = new Document(filePath);
DocumentBuilder builder = new DocumentBuilder(doc);

foreach (Section section in doc.Sections)
{
    HeaderFooter header = section.HeadersFooters[HeaderFooterType.HeaderFirst];
    header?.Remove();

    header = section.HeadersFooters[HeaderFooterType.HeaderPrimary];
    header?.Remove();

    header = section.HeadersFooters[HeaderFooterType.HeaderEven];
    header?.Remove();

}             

builder.MoveToHeaderFooter(Aspose.Words.HeaderFooterType.HeaderPrimary);
builder.Write("This is the header I want to add");

However this failed our tests as it is also removing any headers that the end user may or may not have added.
So does anybody have any ideas of what approach we could take to apply our own header text but leave the user text in its original state.
My first thoughts we to append our header however next time the document is save I have no way of identify if the header is my header or a user header and this resulted in duplicates of our header being added each time the user saved the document. With our PDF equivalent we are available to set an ID and we use this for identifying if changes are required but I haven’t found any option with Word to set an id?
Any ideas or thoughts would be appreciated.

@dev0314

To preserve existing user headers while adding your own text to a Word document, you can modify your approach to avoid removing the user’s headers. Instead of clearing all headers, you can check if a header already exists and only add your text if it doesn’t. Here’s a suggested approach:

  1. Check for Existing Headers: Before adding your header text, check if the header already contains any content. If it does, you can either skip adding your text or append it based on your requirements.

  2. Use DocumentBuilder: Utilize the DocumentBuilder to navigate to the header and add your text conditionally.

Here’s an example code snippet demonstrating this approach:

Document doc = new Document(filePath);
DocumentBuilder builder = new DocumentBuilder(doc);

foreach (Section section in doc.Sections)
{
    // Check if the primary header already has content
    HeaderFooter primaryHeader = section.HeadersFooters[HeaderFooterType.HeaderPrimary];
    if (primaryHeader != null && primaryHeader.ChildNodes.Count > 0)
    {
        // Header already has content, you can choose to append or skip
        // For example, to append your text:
        builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);
        builder.Write(" - Additional Header Text");
    }
    else
    {
        // If no content, add your header text
        builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);
        builder.Write("This is the header I want to add");
    }
}

doc.Save(filePath);

Key Points:

  • This code checks if the primary header already contains any child nodes (content). If it does, it appends your text; otherwise, it adds your header text.
  • This way, you can ensure that existing user headers are preserved while still adding your own content.

By following this method, you can avoid the issue of removing user-added headers and prevent duplicates when the document is saved multiple times.

For more detailed information on working with headers and footers in Aspose.Words, you can refer to the official documentation here.

Thanks. And this approach works on the initial save.
However, if I take the example code you provided, on the second save of the document it would duplicate the header as it has no way of identifying if the ChildNodes.Count > 1 because of a user header or a programmatically added header.

@dev0314 You can wrap content inserted into the header/footer with a bookmark and use this bookmark to identify/remove content inserted through the code.

Document doc = new Document(@"C:\Temp\in.docx");
DocumentBuilder builder = new DocumentBuilder(doc);
// Move to header.
builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);

// Start bookmark.
string bkName = "my_header";
builder.StartBookmark(bkName);
// Insert some content.
builder.Write("This is header content inserted through the code.");
// End bookmark.
builder.EndBookmark(bkName);

doc.Save(@"C:\Temp\out.docx");

// Now load the resulting document, remove content from the bookmakr and insert some new content.
Document doc2 = new Document(@"C:\Temp\out.docx");   
DocumentBuilder builder2 = new DocumentBuilder(doc2);
doc2.Range.Bookmarks[bkName].Text = "";
builder2.MoveToBookmark(bkName, true, true);
builder2.Write("some new contnet.");
doc2.Save(@"C:\Temp\out1.docx");

Hi @alexey.noskov - thanks very much for this suggestion - this has resolved the issue I was having.

1 Like