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
相关产品推荐
相关产品推荐

