如何通过页码访问OpenXML内容

本文关键字:OpenXML 内容 访问 何通过 | 更新日期: 2023-09-27 18:12:37

使用OpenXML,我可以通过页码读取文档内容吗?

wordDocument.MainDocumentPart.Document.Body给出了完整文档的内容。

  public void OpenWordprocessingDocumentReadonly()
        {
            string filepath = @"C:'...'test.docx";
            // Open a WordprocessingDocument based on a filepath.
            using (WordprocessingDocument wordDocument =
                WordprocessingDocument.Open(filepath, false))
            {
                // Assign a reference to the existing document body.  
                Body body = wordDocument.MainDocumentPart.Document.Body;
                int pageCount = 0;
                if (wordDocument.ExtendedFilePropertiesPart.Properties.Pages.Text != null)
                {
                    pageCount = Convert.ToInt32(wordDocument.ExtendedFilePropertiesPart.Properties.Pages.Text);
                }
                for (int i = 1; i <= pageCount; i++)
                {
                    //Read the content by page number
                }
            }
        }

MSDN参考


更新1:

看起来分页符设置如下

<w:p w:rsidR="003328B0" w:rsidRDefault="003328B0">
        <w:r>
            <w:br w:type="page" />
        </w:r>
    </w:p>

所以现在我需要将XML与上面的检查分开,并为每个检查取InnerTex,这将为我提供页面文本。

现在的问题是我如何用上面的检查分割XML ?


更新2:

只有在有分页符时才设置分页符,但如果文本从一个页面浮动到其他页面,则没有设置分页符XML元素,因此它又回到了如何识别页面分隔的相同挑战。

如何通过页码访问OpenXML内容

您不能仅在OOXML数据级别上通过页码引用OOXML内容。

  • 硬分页符 不是问题;硬分页符可以计数。
  • 软分页 是问题所在。这些都是根据实现了换行和分页算法依赖的;它不是OOXML数据所固有的。什么都没有数。

那么w:lastRenderedPageBreak呢?它是软分页符在文档最后渲染时的位置记录。不,w:lastRenderedPageBreak一般也没有帮助,因为:

  • 根据定义,w:lastRenderedPageBreak的位置是陈旧的,当内容自上次被一个程序打开以来被更改内容。
  • 在MS Word的实现中,w:lastRenderedPageBreak在各种情况下都是不可靠的,包括
    1. 当表跨越两个页面
    2. 下一页以空段落开头
    3. ,多栏布局,文本框从一个新栏开始
    4. ,大图片或长空白行

如果您愿意接受依赖Word自动化,以及它所有固有的许可和服务器操作限制,那么您就有机会确定页面边界、页码、页数等。

否则,唯一真正的答案是超越依赖于专有的、特定于实现的分页算法的基于页面的引用框架。

我就是这么做的

  public void OpenWordprocessingDocumentReadonly()
        {
            string filepath = @"C:'...'test.docx";
            // Open a WordprocessingDocument based on a filepath.
            Dictionary<int, string> pageviseContent = new Dictionary<int, string>();
            int pageCount = 0;
            using (WordprocessingDocument wordDocument =
                WordprocessingDocument.Open(filepath, false))
            {
                // Assign a reference to the existing document body.  
                Body body = wordDocument.MainDocumentPart.Document.Body;
                if (wordDocument.ExtendedFilePropertiesPart.Properties.Pages.Text != null)
                {
                    pageCount = Convert.ToInt32(wordDocument.ExtendedFilePropertiesPart.Properties.Pages.Text);
                }
                int i = 1;
                StringBuilder pageContentBuilder = new StringBuilder();
                foreach (var element in body.ChildElements)
                {
                    if (element.InnerXml.IndexOf("<w:br w:type='"page'" />", StringComparison.OrdinalIgnoreCase) < 0)
                    {
                        pageContentBuilder.Append(element.InnerText);
                    }
                    else
                    {
                        pageviseContent.Add(i, pageContentBuilder.ToString());
                        i++;
                        pageContentBuilder = new StringBuilder();
                    }
                    if (body.LastChild == element && pageContentBuilder.Length > 0)
                    {
                        pageviseContent.Add(i, pageContentBuilder.ToString());
                    }
                }
            }
        }

缺点:这并不是在所有情况下都有效。这只会在你有换行符的时候起作用,但是如果你的文本从第1页延伸到第2页,就没有标识符来知道你在第二页。

不幸的是,As为什么只有一些页码存储在docx文件的XML中?答:docx不包含可靠的页码服务。Xml文件没有页码,直到microsoft Word打开它并动态呈现。即使你阅读openxml文档,如https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.pagenumber?view=openxml-2.8.1 .

你可以解压缩一些docx文件,然后搜索"page"或";pg"。然后你就知道了。在我的情况下,我对不同类型的docx文件都这样做。都告诉我同样的事实。很高兴这对你有帮助。

List<</p>

Listpage段落=所有段落。Where (x=>x. descendants ().Count() ==1) .Select(x =>.ToList x) .Distinct () ();

将docx重命名为zip。打开docProps'app.xml文件。:

 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes">
  <Template>Normal</Template>
  <TotalTime>0</TotalTime>
  <Pages>1</Pages>
  <Words>141</Words>
  <Characters>809</Characters>
  <Application>Microsoft Office Word</Application>
  <DocSecurity>0</DocSecurity>
  <Lines>6</Lines>
  <Paragraphs>1</Paragraphs>
  <ScaleCrop>false</ScaleCrop>
  <HeadingPairs>
    <vt:vector size="2" baseType="variant">
      <vt:variant>
        <vt:lpstr>Название</vt:lpstr>
      </vt:variant>
      <vt:variant>
        <vt:i4>1</vt:i4>
      </vt:variant>
    </vt:vector>
  </HeadingPairs>
  <TitlesOfParts>
    <vt:vector size="1" baseType="lpstr">
      <vt:lpstr/>
    </vt:vector>
  </TitlesOfParts>
  <Company/>
  <LinksUpToDate>false</LinksUpToDate>
  <CharactersWithSpaces>949</CharactersWithSpaces>
  <SharedDoc>false</SharedDoc>
  <HyperlinksChanged>false</HyperlinksChanged>
  <AppVersion>14.0000</AppVersion>
</Properties>

OpenXML库从<Pages>1</Pages> property读取wordDocument.ExtendedFilePropertiesPart.Properties.Pages.Text。这些属性只能由winword应用程序创建。如果word文档更改wordDocument.ExtendedFilePropertiesPart.Properties.Pages.Text不是实际的。如果word文档以编程方式创建,则使用wordDocument。ExtendedFilePropertiesPart通常为空