OfficeIMO
OfficeIMO copied to clipboard
How to align page number in Footer
I have seen how you can add page numbers to the footer using .AddPageNumber()
but how can I position this with other content I have in the footer.
We have done this in the header by using a table (I'm not sure if there is a better way):
wordDocument.AddHeadersAndFooters();
var headerTable = wordDocument.Header.Default.AddTable(1, 3, WordTableStyle.TableNormal);
headerTable.WidthType = TableWidthUnitValues.Pct;
headerTable.Width = WordTableGenerator.OneHundredPercentWidth;
var para = headerTable.Rows[0].Cells[0].AddParagraph();
para.AddImage(headerLogo, "logo.png", targetWidth, targetHeight);
para.ParagraphAlignment = JustificationValues.Left;
var header = headerTable.Rows[0].Cells[1].AddParagraph(headerText);
header.ParagraphAlignment = JustificationValues.Center;
I can't do this in the Footer as the AddPageNumber
method is only available on the WordFooter
type. So I have to do this:
var footer = wordDocument.Footer.Default.AddParagraph(footerText);
footer.ParagraphAlignment = JustificationValues.Center;
var pageNumber = wordDocument.Footer.Default.AddPageNumber(WordPageNumberStyle.PageNumberXofY);
pageNumber.ParagraphAlignment = JustificationValues.Right;
Meaning I end up with my footer text on one line and the Page Number on another - rather than side by side in one Row as I would prefer.
Well, the way to do it is to expand AddPageNumber to work on Paragraphs, rather then on Documents directly, and use same method as you use for header with a table. I guess poor implementation on my side, that would require fixing. Or you can use Fields, as after all it's all field codes
There's no direct way now. So you either have to fix my implementation that will work with both document and paragraph or build your own Paragraph with fields
namespace OfficeIMO.Examples.Word {
internal static partial class Fields {
internal static void Example_DocumentWithFields02(string folderPath, bool openWord) {
Console.WriteLine("[*] Creating standard document with tables");
string filePath = System.IO.Path.Combine(folderPath, "Document with Fields02.docx");
using (WordDocument document = WordDocument.Create(filePath)) {
var paragraph = document.AddParagraph("Basic paragraph");
paragraph.ParagraphAlignment = JustificationValues.Center;
document.AddParagraph();
document.AddHeadersAndFooters();
// added page number using fields which triggers fields refresh
document.AddField(WordFieldType.NumPages);
document.AddField(WordFieldType.Author);
document.AddField(WordFieldType.GreetingLine);
// added page number using dedicated way
var pageNumber = document.Header.Default.AddPageNumber(WordPageNumberStyle.Roman);
document.Save(openWord);
}
}
}
}
for example:
namespace OfficeIMO.Examples.Word {
internal static partial class Fields {
internal static void Example_DocumentWithFields02(string folderPath, bool openWord) {
Console.WriteLine("[*] Creating standard document with tables");
string filePath = System.IO.Path.Combine(folderPath, "Document with Fields02.docx");
using (WordDocument document = WordDocument.Create(filePath)) {
var paragraph = document.AddParagraph("Basic paragraph");
paragraph.ParagraphAlignment = JustificationValues.Center;
document.AddParagraph();
document.AddHeadersAndFooters();
// added page number using fields which triggers fields refresh
document.AddField(WordFieldType.Page).AddText(" of ").AddField(WordFieldType.NumPages);
document.AddField(WordFieldType.Author);
document.AddField(WordFieldType.GreetingLine);
// added page number using dedicated way
var pageNumber = document.Header.Default.AddPageNumber(WordPageNumberStyle.Roman);
document.Save(openWord);
}
}
}
}
And you can use fields anywhere
Thanks for your prompt and thorough response.
I have tried doing it like this:
var footerTable = wordDocument.Footer.Default.AddTable(1, 3, WordTableStyle.TableNormal);
footerTable.WidthType = TableWidthUnitValues.Pct;
footerTable.Width = WordTableGenerator.OneHundredPercentWidth;
var footer = footerTable.Rows[0].Cells[1].AddParagraph(footerText);
footer.ParagraphAlignment = JustificationValues.Center;
var pageNumber = footerTable.Rows[0].Cells[2].AddParagraph();
pageNumber.ParagraphAlignment = JustificationValues.Right;
pageNumber
.AddText("Page ")
.AddField(WordFieldType.Page)
.AddText(" of ")
.AddField(WordFieldType.NumPages);
Which works:
Except I get this pop up when I open the document:
Those are fields, which I guess need to be updated on open to be able to tell which page are those. I would guess this is by design. But if the same doesn't happen with the other way, there must be some difference for that.
Yh with the standard .AddPageNumber
method I didn't get that popup.
Well then that needs investigation what is different and why one triggers and the other one doesn't. Probably better to fix 1st method to add to paragraph, but that requires some work.
Do you know what's needed to achieve that - is it just a lot of refactoring? I would offer to help but I likely won't have much time - though with some guidance on what's needed it might be more possible.
The code starts here:
https://github.com/EvotecIT/OfficeIMO/blob/470cef22a54c3d736e88c91bffc955b515e635c7/OfficeIMO.Word/WordFooter.cs#L57-L60
When you use it, it does this:
document.AddHeadersAndFooters();
document.Footer.Default.AddPageNumber(WordPageNumberStyle.PageNumberXofY);
Then if you add paragraphs there:
document.AddHeadersAndFooters();
document.Footer.Default.AddParagraph("Test1");
document.Footer.Default.AddParagraph("Test2");
document.Footer.Default.AddPageNumber(WordPageNumberStyle.PageNumberXofY);
That means we are basically applying it to last element in footer. Looking at how it behaves I would say you need to modify this line, and instead of appending it to footer directly, you would need to allow assigning it to last paragraph wherever you want..
https://github.com/EvotecIT/OfficeIMO/blob/470cef22a54c3d736e88c91bffc955b515e635c7/OfficeIMO.Word/WordPageNumber.cs#L101C47-L101C47
At least that's my guess, not tested.