You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#使用OpenXml获取docx文档总页数及段落所属页码的实现示例

实现思路

Word文档的页码属于渲染层信息,OpenXML本身不会实时计算分页,我们读取的是Word最后一次保存文档时写入的预渲染分页标记LastRenderedPageBreak和内置文档属性里的总页数信息,前提是文档已经在Word中打开保存过,否则无法获取正确的分页数据。

前置依赖
  • 安装NuGet包:DocumentFormat.OpenXml(建议使用2.15及以上稳定版本)
完整代码示例
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Collections.Generic;
using System.Linq;

public class DocxParagraphReader
{
    /// <summary>
    /// 段落信息类
    /// </summary>
    public class ParagraphInfo
    {
        /// <summary>
        /// 段落文本内容
        /// </summary>
        public string Text { get; set; }
        /// <summary>
        /// 段落所在页码
        /// </summary>
        public int PageNumber { get; set; }
    }

    /// <summary>
    /// 读取docx文档的总页数和所有段落的页码信息
    /// </summary>
    /// <param name="filePath">docx文件路径</param>
    /// <param name="totalPages">输出总页数</param>
    /// <returns>段落信息列表</returns>
    public static List<ParagraphInfo> ReadParagraphsWithPageNumber(string filePath, out int totalPages)
    {
        var result = new List<ParagraphInfo>();
        totalPages = 0;

        using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, false))
        {
            // 读取总页数,来自文档最后一次渲染的内置属性
            if (doc.ExtendedFilePropertiesPart?.Properties?.Pages != null)
            {
                totalPages = int.Parse(doc.ExtendedFilePropertiesPart.Properties.Pages.Text);
            }

            int currentPage = 1;
            // 遍历文档所有元素
            var elements = doc.MainDocumentPart.Document.Body.Elements();
            foreach (var element in elements)
            {
                // 遇到分页标记就更新当前页码
                if (element.Descendants<LastRenderedPageBreak>().Any())
                {
                    currentPage++;
                }

                // 匹配到段落就记录信息
                if (element is Paragraph para)
                {
                    result.Add(new ParagraphInfo
                    {
                        Text = para.InnerText,
                        PageNumber = currentPage
                    });
                }
            }
        }

        return result;
    }

    // 调用示例
    public static void Main(string[] args)
    {
        string docPath = @"C:\test\example.docx";
        var paragraphs = ReadParagraphsWithPageNumber(docPath, out int totalPages);

        System.Console.WriteLine($"文档总页数:{totalPages}");
        foreach (var para in paragraphs)
        {
            System.Console.WriteLine($"页码{para.PageNumber}:{para.Text}");
        }
    }
}
注意事项
  • 必须保证文档已经用Microsoft Word打开并保存过,否则不会生成LastRenderedPageBreak标记和总页数属性,获取的结果会不准确
  • 如果文档包含域内容(比如自动生成的目录、页码域),需要先在Word中更新所有域后再保存,否则页码可能和实际打开Word看到的页码有偏差
  • 包含分节符、不同页眉页脚设置的复杂文档,建议配合SectionProperties元素的分页属性做额外兼容处理

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 04:54:02