Header and Footer only on last page

Hello,

Describe the case

I’m creating .docx and .pdf documents from HTML templates using Aspose.Words for .Net.

In version 24.2, Aspose.Words for .Net was adding Header and Footer to every page.

I want to upgrade to newest version, but starting from version 24.3, header and footer is only on last page. This is also the case for version 25.3.

There is also a change in Section Break on the end of 3rd page. In v24.2 it was Section Break (Continuous), but in 24.3 and newer it is Section Break (Next Page).

Describe the ask

I’m asking for help with making the header and footer appear on every page, just as it was in version 24.2.
Additionally, can you provide me with a mapping of HTML tags and CSS page breaks to MS Word document? This would make it easier for me to know how the HTML should look like.

Reproduction steps and samples

I’ve attached generated documents and also the code to reproduce the issue. The HTML template I’m using can be found in “minimalrepro.html”.

You can find documents in .pdf and .docx version in “results” folder.

To run reproduction steps, provide a valid licence in “wordsissue\Licences\Aspose.Words.Net.lic”.

You can run the test case with powershell script “testcase.ps1” - it will first add Aspose.Words v24.2 and generate documents, then it will upgrade to v24.3 and generate documents, then it will upgrade to v25.3 and generate the documents, then will change nuget to v24.2. Results will be available in “results” folder. You can also open the .sln and run the test there - results will be saved in the “wordsissue\bin” folder.

asposewords-issue.zip (300.8 KB)

@mlamla

Can you please clarify what specific changes you would like to make to the header and footer settings in your Aspose.Words code to ensure they appear on every page?

I want it to either be backwards compatible or you to help me understand what should I modify, to make the generated documents look the same as it did before package upgrade.

@mlamla To make the things simpler I have simplified the scenario to the following code:

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

builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);
builder.InsertHtml("<b>This is my Cool Header</b>", true);

builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary);
builder.InsertHtml("<b>This is my Cool Footer</b>", true);

builder.MoveToDocumentEnd();
builder.InsertHtml("<p>First</p><div style=\"page-break-before:initial;\"><p>second</p>", false);

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

To resolve the problem and make the code work as expected, you should simply change the order, i.e. insert the document content first and then insert header/footer into the first section of the document:

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

// Insert body.
builder.InsertHtml("<p>First</p><div style=\"page-break-before:initial;\"><p>second</p>", false);

// Move to document start and insert header/footer
builder.MoveToDocumentStart();

builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);
builder.InsertHtml("<b>This is my Cool Header</b>", true);

builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary);
builder.InsertHtml("<b>This is my Cool Footer</b>", true);

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

Returning to your code, you can modify it like this:

documentBuilder.ApplyStyles(documentTemplateStyle)
    .InsertHtmlOnBody(File.ReadAllText(htmlFilePath))
    .InsertHeaderHtml(documentTemplateStyle.HeaderTemplate)
    .InsertFooterHtml(documentTemplateStyle.FooterTemplate);
public static DocumentBuilder InsertHeaderHtml(this DocumentBuilder builder, string htmlTemplate)
{
    builder.MoveToDocumentStart();
    builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary);
    builder.InsertHtml(htmlTemplate, true);
    return builder;
}

public static DocumentBuilder InsertFooterHtml(this DocumentBuilder builder, string html)
{
    builder.MoveToDocumentStart();
    builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary);
    builder.InsertHtml(html, true);
    return builder;
}

Regarding section breaks. You can use the following HTML to insert different types of section breaks:
Continuous:

<br style="clear:both; mso-break-type:section-break" />

Next Page:

<br style="page-break-before:always; clear:both; mso-break-type:section-break" />

Even Page:

<br style="page-break-before:left; clear:both; mso-break-type:section-break" />

Odd Page:

<br style="page-break-before:right; clear:both; mso-break-type:section-break" />

Thank you for rapid response.
Headers and footers are now on every page.
Had some other minor issues later on because i’ve setup the docbuilder.PageSetup → added document body → changed docbuilder.PageSetup.BottomMargin = 0 for footer to start as close to bottom of doc as possible → added footerHtml => this resulted in different footer margins on 1st page compared to any subsequent page.

It’s sad that API does not imply that you should add styling before adding content, and also that you should first add body, and only then add header and footer. Adding some fluent API for document builder would be really nice (i will probably do it in my project now, to clearly show the flow of Aspose’s method invokation).

Also for any feature readers, I’d like to clarify your examples:

builder.InsertHtml("<p>First</p><div style=\"page-break-before:initial;\"><p>second</p>", false);

This creates a document with a single page and both paragraphs on the single page.

This can be fixed by:
Adding some text after div - results in generating document with 2 pages.

builder.InsertHtml(@"<p>First</p><div style=""page-break-before:always; clear:both; mso-break-type:section-break"" /> . <p>second</p>"

Also changing div to br seems to help - document with 2 pages is created.

builder.InsertHtml(@"<p>First</p><br style=""page-break-before:always; clear:both; mso-break-type:section-break"" /><p>second</p>"
    , false);

Anyway, thank you very much for help. My issue is fixed now and I can upgrade to latest Aspose.Words for .Net :slight_smile:

Additionally, can you provide me with a mapping of HTML tags and CSS page breaks to MS Word document? This would make it easier for me to know how the HTML should look like.

@mlamla It is perfect that you managed to resolve your problem.

Page break in HTML:

<br style="page-break-before:always; clear:both" />

Column break in HTML:

<br style="clear:both; mso-column-break-before:always" />

Using HTML content for building documents is not always obvious, because Aspose.Words Document Object Model is designed to work with MS Word documents. HTML documents object model is quite different and it is not always possible to provide 100% fidelity after importing HTML. Usually Aspose.Words exports roundtrip information to HTML. So if you would like to check how some MS Word feature is expected by Aspose.Words to be represented in HTML, you can simple convert DOCX document to HTML and see how Aspose.Words writes it.

This advice is what I needed, thank you very much.
We can consider this topic as closed :slight_smile:

1 Like