使用 Java 生成 Word 报告、合同或技术文档时,页码往往需要根据文档结构进行调整。例如,封面不显示页码、正文从指定页面开始编号、目录使用罗马数字而正文使用阿拉伯数字,或者将奇偶页的页码分别放在页面左右两侧。
本文将结合这些常见场景,介绍如何通过 Java 添加和操作 Word 页码,实现不同的页码排版需求。
一、配置 Java Word 文档处理环境
本文使用 Free Spire.Doc for Java 操作 Word 文档。该库支持页眉页脚编辑、页码域插入及分节设置等功能,无需在运行环境中安装 Microsoft Word。
如果使用 Maven,可以在 pom.xml 中添加以下依赖:
xml
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc.free</artifactId>
<version>14.3.1</version>
</dependency>
</dependencies>
如果不使用 Maven,也可以从 Free Spire.Doc for Java 下载页面获取 JAR 包,手动添加到项目中。
二、为 Word 文档添加页码和总页数
Word 通过域(Field)显示当前页码和总页数。使用 Java 插入相应的域后,页码可以随文档分页变化而自动更新。Word 中常用的页码域有:
| 字段类型 | 作用 |
|---|---|
FieldType.Field_Page |
当前页码 |
FieldType.Field_Num_Pages |
整个文档的总页数 |
FieldType.Field_Section_Pages |
当前节的总页数 |
下面的示例在 Word 页脚中插入"第 X 页,共 Y 页",并设置为居中显示。其中 X 为当前页码,Y 为文档的总页数。
java
import com.spire.doc.*;
import com.spire.doc.documents.*;
public class AddPageNumbers {
public static void main(String[] args) {
Document document = new Document();
document.loadFromFile("报告.docx");
// 获取第一个节的页脚
Section section = document.getSections().get(0);
HeaderFooter footer = section.getHeadersFooters().getFooter();
// 添加当前页码和总页数
Paragraph paragraph = footer.addParagraph();
paragraph.appendText("第 ");
paragraph.appendField("CurrentPage", FieldType.Field_Page);
paragraph.appendText(" 页,共 ");
paragraph.appendField("TotalPages", FieldType.Field_Num_Pages);
paragraph.appendText(" 页");
// 设置居中对齐和字号
paragraph.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center);
paragraph.getStyle().getCharacterFormat().setFontSize(10);
document.saveToFile("添加页码后的报告.docx");
document.dispose();
}
}
如果文档共有 12 页,页脚将显示"第 1 页,共 12 页""第 2 页,共 12 页"等内容。
如果只需要显示当前页码,可以省略总页数域:
java
paragraph.appendText("第 ");
paragraph.appendField("CurrentPage", FieldType.Field_Page);
paragraph.appendText(" 页");
页码的位置也可以通过 HorizontalAlignment.Left、Center 或 Right 调整。
注意: 如果文档包含多个节,且各节的页脚保持链接,页码通常可以在后续节中继续显示,无需逐节添加。如果某些节使用独立页脚,则需要为这些节单独设置页码。
三、隐藏 Word 首页页码,让第二页从 1 开始
对于带封面的 Word 报告,用户通常希望第一页不显示页码。
如果只需要隐藏首页页码,可以启用 Word 的"首页不同"设置;如果还希望第二页从 1 开始编号,则可以将起始页码设置为 0。
java
import com.spire.doc.*;
import com.spire.doc.documents.*;
public class HideFirstPageNumber {
public static void main(String[] args) {
Document document = new Document();
document.loadFromFile("报告.docx");
Section section = document.getSections().get(0);
// 启用首页不同设置
section.getPageSetup().setDifferentFirstPageHeaderFooter(true);
// 将起始页码设置为 0
section.getPageSetup().setRestartPageNumbering(true);
section.getPageSetup().setPageStartingNumber(0);
// 只在常规页脚中添加页码,忽略首页页脚
HeaderFooter footer = section.getHeadersFooters().getFooter();
Paragraph paragraph = footer.addParagraph();
paragraph.appendField("PageNumber", FieldType.Field_Page);
paragraph.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center);
document.saveToFile("首页隐藏页码.docx");
document.dispose();
}
}
其中,setRestartPageNumbering(true) 用于设置重新开始页码编号,setPageStartingNumber(0) 则将起始页码修改为0,让第二页对应页码为 1。
这里要求首页页脚为空。如果原文档的首页页脚已经包含页码,还需要单独清空。
如果需要隐藏的不止第一页,例如封面和目录都不显示页码,则可以采用下面的方法。
四、从 Word 指定页面开始添加页码
假设一份 Word 项目报告的前两页分别是封面和目录,正文从第三页开始。你希望封面和目录不显示页码,而正文从 1 开始编号,或者保留原有的页码顺序,从 3 开始显示。
这两种情况都可以通过 Word 的分节功能实现。将封面和目录作为第一节,正文作为第二节,就可以单独设置正文的页脚,并根据需要选择重新编号或延续原有页码编号。
4.1 从指定页面开始编号
首先,在 Word 中将光标放在正文开始的位置,选择 "布局"→"分隔符"→"下一页",插入分节符。
文档结构和预期效果如下:
| 节 | 实际页面 | 页码显示 |
|---|---|---|
| 第一节:封面和目录 | 第 1--2 页 | 不显示 |
| 第二节:正文 | 第 3 页 | 1 |
| 第二节:正文 | 第 4 页 | 2 |
| 第二节:正文 | 第 5 页 | 3 |
接下来,获取第二节,解除其页脚与上一节的链接,并将起始页码设置为 1。
java
import com.spire.doc.*;
import com.spire.doc.documents.*;
public class AddPageNumbersFromSpecificPage {
public static void main(String[] args) {
Document document = new Document();
document.loadFromFile("项目报告.docx");
// 获取正文所在的第二节
Section section = document.getSections().get(1);
// 解除与上一节的页脚链接
HeaderFooter footer = section.getHeadersFooters().getFooter();
footer.setLinkToPrevious(false);
// 从 1 开始编号
section.getPageSetup().setRestartPageNumbering(true);
section.getPageSetup().setPageStartingNumber(1);
// 添加页码
Paragraph paragraph = footer.addParagraph();
paragraph.appendField("PageNumber", FieldType.Field_Page);
paragraph.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center);
document.saveToFile("从指定页面开始添加页码.docx");
document.dispose();
}
}
注意,get(1) 获取的是第二个节,而不是第二页。分节符必须插入在正文开始的位置。
补充:从指定页面开始显示原有页码
如果希望封面和目录不显示页码,而第三页正文显示 3,后续页面依次显示 4、5、6,则不需要让正文重新从 1 开始编号。
只需将上述代码中的重新编号设置改为:
java
// 延续前一节的编号
section.getPageSetup().setRestartPageNumbering(false);
如果文档已经存在页码域,只是想修改某个节的起始编号,可以直接修改该节的页码设置,无需重复插入页码。
4.2 仅为 Word 指定章节添加页码
有些报告不仅要求前面的封面不显示页码,还希望后面的附录也不显示页码。
例如:
| 文档部分 | 页码显示 |
|---|---|
| 第一节:封面 | 不显示 |
| 第二节:正文 | 1、2、3...... |
| 第三节:附录 | 不显示 |
首先,需要在封面、正文和附录之间插入分节符,将文档划分为三个节。接下来,为第二节添加页码,并解除第三节与第二节之间的页脚链接。
java
import com.spire.doc.*;
import com.spire.doc.documents.*;
public class AddPageNumbersToSpecificSection {
public static void main(String[] args) {
Document document = new Document();
document.loadFromFile("项目报告.docx");
// 获取正文所在的第二节
Section section = document.getSections().get(1);
HeaderFooter footer = section.getHeadersFooters().getFooter();
footer.setLinkToPrevious(false);
// 正文从 1 开始编号
section.getPageSetup().setRestartPageNumbering(true);
section.getPageSetup().setPageStartingNumber(1);
Paragraph paragraph = footer.addParagraph();
paragraph.appendField("PageNumber", FieldType.Field_Page);
paragraph.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center);
// 获取附录所在的第三节
Section appendix = document.getSections().get(2);
HeaderFooter appendixFooter =
appendix.getHeadersFooters().getFooter();
// 解除页脚链接,并清除附录的页脚内容
appendixFooter.setLinkToPrevious(false);
appendixFooter.getChildObjects().clear();
appendixFooter.addParagraph();
document.saveToFile("指定章节添加页码.docx");
document.dispose();
}
}
为了避免附录继承正文页码,需要解除第三节的页脚链接后,再清除不需要的页脚内容。注意,getChildObjects().clear() 会删除整个页脚。如果其中还包含日期、版权声明或其他文字,应只处理页码域,而不是直接清空页脚。
五、为 Word 不同章节设置不同的页码格式(罗马数字和阿拉伯数字)
论文、书籍和技术手册经常需要为不同部分设置不同的页码格式。例如,目录使用小写罗马数字,正文使用阿拉伯数字。
| 文档部分 | 页码格式 |
|---|---|
| 目录 | i、ii、iii |
| 正文 | 1、2、3 |
这种情况下,可以通过分节符将目录和正文划分为两个节,再使用 PageNumberStyle 分别设置页码格式。
常用的枚举值如下:
| 枚举值 | 显示效果 |
|---|---|
PageNumberStyle.Arabic |
1、2、3 |
PageNumberStyle.Roman_Lower |
i、ii、iii |
PageNumberStyle.Roman_Upper |
I、II、III |
PageNumberStyle.Letter_Lower |
a、b、c |
PageNumberStyle.Letter_Upper |
A、B、C |
下面的代码将第一节设置为小写罗马数字页码,第二节设置为阿拉伯数字页码,并让两个节分别从 1 开始编号。
java
import com.spire.doc.*;
import com.spire.doc.documents.*;
public class SetDifferentPageNumberStyles {
public static void main(String[] args) {
Document document = new Document();
document.loadFromFile("论文.docx");
// 第一节:目录使用小写罗马数字
Section tocSection = document.getSections().get(0);
tocSection.getPageSetup().setRestartPageNumbering(true);
tocSection.getPageSetup().setPageStartingNumber(1);
tocSection.getPageSetup().setPageNumberStyle(
PageNumberStyle.Roman_Lower);
HeaderFooter tocFooter =
tocSection.getHeadersFooters().getFooter();
Paragraph tocParagraph = tocFooter.addParagraph();
tocParagraph.appendField("PageNumber", FieldType.Field_Page);
tocParagraph.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center);
// 第二节:正文使用阿拉伯数字
Section bodySection = document.getSections().get(1);
HeaderFooter bodyFooter =
bodySection.getHeadersFooters().getFooter();
bodyFooter.setLinkToPrevious(false);
bodySection.getPageSetup().setRestartPageNumbering(true);
bodySection.getPageSetup().setPageStartingNumber(1);
bodySection.getPageSetup().setPageNumberStyle(
PageNumberStyle.Arabic);
Paragraph bodyParagraph = bodyFooter.addParagraph();
bodyParagraph.appendField("PageNumber", FieldType.Field_Page);
bodyParagraph.getFormat().setHorizontalAlignment(
HorizontalAlignment.Center);
document.saveToFile("不同章节页码格式.docx");
document.dispose();
}
}
假设目录占 3 页,正文占 5 页,生成的页码分别为:
- 目录:i、ii、iii。
- 正文:1、2、3、4、5。
setPageNumberStyle() 控制数字格式,而 setPageStartingNumber() 控制起始值。
如果文档还包含封面,可以将封面单独划分为一个节,避免封面与目录共用页码设置。
六、让 Word 奇偶页的页码分别显示在左右两侧
对于需要双面打印的书籍或技术手册,通常会将页码放在页面外侧,方便翻阅。例如,奇数页的页码位于右侧,偶数页位于左侧。
| 实际页面 | 页码 | 显示位置 |
|---|---|---|
| 第 1 页 | 1 | 右侧 |
| 第 2 页 | 2 | 左侧 |
| 第 3 页 | 3 | 右侧 |
| 第 4 页 | 4 | 左侧 |
可以启用 Word 的"奇偶页不同"设置,再分别为奇数页和偶数页添加页码。
以下示例针对只有一个节的多页 Word 文档:
java
import com.spire.doc.*;
import com.spire.doc.documents.*;
public class DifferentOddEvenPageNumbers {
public static void main(String[] args) {
Document document = new Document();
document.loadFromFile("技术手册.docx");
Section section = document.getSections().get(0);
// 启用奇偶页不同设置
section.getPageSetup()
.setDifferentOddAndEvenPagesHeaderFooter(true);
// 奇数页:页码右对齐
HeaderFooter oddFooter =
section.getHeadersFooters().getOddFooter();
Paragraph oddParagraph = oddFooter.addParagraph();
oddParagraph.appendField("OddPageNumber", FieldType.Field_Page);
oddParagraph.getFormat().setHorizontalAlignment(
HorizontalAlignment.Right);
// 偶数页:页码左对齐
HeaderFooter evenFooter =
section.getHeadersFooters().getEvenFooter();
Paragraph evenParagraph = evenFooter.addParagraph();
evenParagraph.appendField("EvenPageNumber", FieldType.Field_Page);
evenParagraph.getFormat().setHorizontalAlignment(
HorizontalAlignment.Left);
document.saveToFile("奇偶页页码设置.docx");
document.dispose();
}
}
奇偶页使用的都是 Field_Page 域,页码仍然按照 1、2、3......连续编号,不需要分别计算奇数和偶数。
如果文档同时启用了"首页不同",还需要单独检查首页页脚。如果包含多个节,则应检查各节的奇偶页页脚和继承关系。
七、常见问题与注意事项
1. 插入了分节符,为什么页码仍然影响其他章节?
Word 中不同节的页眉和页脚可能仍然链接在一起。即使插入了分节符,也不代表每个节的页脚自动独立。
如果需要分别编辑页脚,可以解除与上一节的链接:
java
HeaderFooter footer = section.getHeadersFooters().getFooter();
footer.setLinkToPrevious(false);
另外,get(1) 指的是第二个节,并非第二页。应确认分节符插入的位置正确,且目标内容属于预期的节。
2. 为什么添加了页码却没有显示?
检查文档是否启用了"首页不同"或"奇偶页不同"。
这两种设置会让 Word 使用不同类型的页脚。如果页码添加在普通页脚中,但当前页面使用首页页脚或偶数页页脚,就可能看不到预期的页码。
需要根据文档设置,检查 getFirstPageFooter()、getOddFooter() 或 getEvenFooter() 对应的内容。
3. 为什么页码或总页数没有更新?
PAGE 和 NUMPAGES 是动态域,显示结果需要根据文档的实际分页情况计算。
如果修改了文档内容、页边距或分节结构,可以使用 Microsoft Word 打开生成的文档,更新域后检查页码和总页数。或者使用 Java 在保存文档前尝试启用域更新:
java
// 启用域更新
document.isUpdateFields(true);
总结
Word 页码设置主要涉及页码域、页眉页脚和分节控制。简单文档可以直接插入页码域;需要隐藏首页、从指定页面编号或使用不同数字格式时,则应根据文档结构选择相应的设置。
在 Java 项目中处理这些需求时,尤其要注意分节符的位置,以及不同节之间的页脚链接关系,避免出现页码重复、编号错误或页码显示在不需要的位置等问题。