You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用POI为Word不同章节设置差异化页码(封面/目录/正文)

当然可以实现!用Apache POI处理Word文档的分区页码是很常见的需求,咱先得搞明白Word的核心逻辑——分节,不同的页码格式必须放在独立的节里,每个节能单独控制页码规则。接下来我一步步给你拆解实现方式:

核心思路

把文档拆成三个独立的节:

  1. 封面节:无页码
  2. 目录节:使用大写罗马数字(I、II、III...)页码
  3. 正文节:使用小写希腊数字(α、β、γ...)页码

每个节通过分节符分隔,分别配置页码规则即可。下面是针对.docx格式(XWPF模块)的完整代码示例:

import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;

public class WordPageNumberSetup {
    public static void main(String[] args) throws IOException {
        try (XWPFDocument doc = new XWPFDocument()) {

            // -------------------------- 1. 封面节:无页码 --------------------------
            XWPFParagraph coverTitle = doc.createParagraph();
            XWPFRun coverRun = coverTitle.createRun();
            coverRun.setText("文档封面");
            coverRun.setFontSize(24);
            coverRun.setBold(true);
            coverTitle.setAlignment(ParagraphAlignment.CENTER);
            
            // 配置封面节的页码规则:无页码,且后续节重置计数
            CTSectionPr coverSectionPr = doc.getDocument().getBody().addNewSectPr();
            CTPageNumber coverPageNum = coverSectionPr.addNewPgNum();
            coverPageNum.setFmt(STNumberFormat.NONE);
            coverPageNum.setStart(BigInteger.ZERO);

            // 插入下一页分节符,分隔封面与目录
            XWPFParagraph sectionBreak1 = doc.createParagraph();
            sectionBreak1.setPageBreak(true);
            CTPPr breakPr1 = sectionBreak1.getCTP().addNewPPr();
            breakPr1.addNewSectPr().set(coverSectionPr);

            // -------------------------- 2. 目录节:罗马数字页码 --------------------------
            XWPFParagraph tocTitle = doc.createParagraph();
            XWPFRun tocRun = tocTitle.createRun();
            tocRun.setText("目录");
            tocRun.setFontSize(20);
            tocRun.setBold(true);
            tocTitle.setAlignment(ParagraphAlignment.CENTER);
            
            // 配置目录节的页码规则:大写罗马数字,从I开始
            CTSectionPr tocSectionPr = CTSectionPr.Factory.newInstance();
            CTPageNumber tocPageNum = tocSectionPr.addNewPgNum();
            tocPageNum.setFmt(STNumberFormat.UPPER_ROMAN);
            tocPageNum.setStart(BigInteger.ONE);

            // 插入下一页分节符,分隔目录与正文
            XWPFParagraph sectionBreak2 = doc.createParagraph();
            sectionBreak2.setPageBreak(true);
            CTPPr breakPr2 = sectionBreak2.getCTP().addNewPPr();
            breakPr2.addNewSectPr().set(tocSectionPr);

            // -------------------------- 3. 正文节:希腊数字页码 --------------------------
            XWPFParagraph contentTitle = doc.createParagraph();
            XWPFRun contentRun = contentTitle.createRun();
            contentRun.setText("正文第一章");
            contentRun.setFontSize(18);
            contentRun.setBold(true);
            
            // 添加正文内容示例
            XWPFParagraph contentPara = doc.createParagraph();
            contentPara.createRun().setText("这里是正文内容,测试希腊数字页码效果...");

            // 配置正文节的页码规则:小写希腊数字,从α开始
            CTSectionPr contentSectionPr = CTSectionPr.Factory.newInstance();
            CTPageNumber contentPageNum = contentSectionPr.addNewPgNum();
            contentPageNum.setFmt(STNumberFormat.LOWER_GREEK);
            contentPageNum.setStart(BigInteger.ONE);

            // 给正文添加页脚页码(居中显示)
            XWPFFooter footer = doc.createFooter(HeaderFooterType.DEFAULT);
            XWPFParagraph footerPara = footer.createParagraph();
            footerPara.setAlignment(ParagraphAlignment.CENTER);
            XWPFRun footerRun = footerPara.createRun();
            // 插入Word页码域,实现自动计数
            footerRun.getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
            footerRun.getCTR().addNewInstrText().setStringValue("PAGE");
            footerRun.getCTR().addNewFldChar().setFldCharType(STFldCharType.END);

            // 将正文节的配置应用到文档末尾
            doc.getDocument().getBody().setSectPr(contentSectionPr);

            // 写入输出文件
            try (FileOutputStream out = new FileOutputStream("MultiPageNumberDoc.docx")) {
                doc.write(out);
            }
        }
    }
}
关键细节说明
  • 分节符的作用:每个分节符会将文档划分为独立的节,确保各节的页码规则互不干扰
  • 页码格式枚举STNumberFormat类中定义了所有支持的页码格式,比如:
    • UPPER_ROMAN:大写罗马数字(I、II、III)
    • LOWER_GREEK:小写希腊数字(α、β、γ)
    • NONE:不显示页码
  • 页码域:正文的页码通过插入PAGE域实现自动计数,而非固定文本,这样Word打开后会自动更新页码
注意事项
  • 建议使用Apache POI 4.1.2及以上版本,API更稳定,兼容性更好
  • 如果需要处理旧版.doc格式(HWPF模块),API逻辑类似但具体类名会有差异
  • 打开生成的文档后,若页码未自动显示,可按F9刷新域即可

内容的提问来源于stack exchange,提问作者bill

火山引擎 最新活动