首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何基于openxmlelement获取页码

如何基于openxmlelement获取页码
EN

Stack Overflow用户
提问于 2017-04-29 20:39:14
回答 3查看 3K关注 0票数 1

对于段落对象,如何使用OpenXMLSDK2.5确定它位于哪个页面?

我已经获得了文档中的所有子元素,并使用此方法获取了内部文本。

代码语言:javascript
运行
复制
   foreach (var i in mainPart.Document.ChildElements.FirstOrDefault().ChildElements)
        {
            ParagraphElements.Add(i); //openxmlelement list
        }

我想要相应段落的页码。例如,我有“这是标题1”标记为样式标题1,这将在TOC中更新。所以我需要传递页码

提前感谢

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-05-09 07:48:27

经过大量的实地工作后,我发现,使用openxml元素无法检索页码。我们可以接近它。但我们不能确定。因为页码是由文字处理器布局引擎呈现的。在将所有OpenXML元素传递给字处理器后,就会发生这种情况。我们可以用LastRenderedPageBreak计算它。但我们不能确定元素的位置是否正确。

因此,我建议使用UpdateFieldsOnOpen或Macro来寻找更简单的解决方案。

票数 0
EN

Stack Overflow用户

发布于 2017-04-30 03:58:40

页面在由文字处理器呈现之前不存在OpenXML格式。

计算给定段落应该出现在哪一页上所需的元数据是可用的,但它远不是一个简单的操作。

若要验证原始OpenXML标记中不存在页号,请执行以下操作:

  1. 将以".docx“结尾的Word文档的副本重命名为以".zip”结尾。
  2. 在这个zip归档文件中,打开名为"word“的子目录。
  3. 在"word“中打开"document.xml”。

此文件包含mainPart.Document调用的XML内容。"document.xml“文件有一个节点,<document>...</document>,它又有一个子节点,<body>...</body>,它反过来保存您感兴趣的内容。

在使用OpenXML文档时,我发现OpenXML SDK中的抽象有时会分散注意力。幸运的是,使用LINQ探索原始标记非常简单。例如,您的电话:

代码语言:javascript
运行
复制
var childrenFromOpenXmlSdk = mainPart.Document.ChildElements.Single().ChildElements;

相当于LINQ中的以下内容:

代码语言:javascript
运行
复制
IEnumerable<XElement> childrenFromLinqToXml = 
    XElement.Load("[path]/[file]/word/document.xml")
            .Elements()
            .Single()
            .Elements();`

检查childrenFromLinqToXml中的元素,您将没有发现任何页码信息。

您可能会在TOC本身的原始标记中看到缓存的页码,但这些将是由内容标记或表单字段定义的先前呈现的工件。

如果需要以编程方式构建TOC,请查看以下站点:

  1. OfficeOpenXML.com关于TOCs的参考文章
代码语言:javascript
运行
复制
- This is a helpful reference for the ECMA-376 specification of OpenXML.

  1. Eric White的屏幕“探索Open文档中的目录”
代码语言:javascript
运行
复制
- Eric White is a leading authority on all things OpenXML. His `ericwhite.com/blog` is well-worth a look when you find yourself at the intersections of XML markup and on-screen rendering.

跟进赛的意见

嗨,奥斯汀·德伦斯基,我创建了TOC并以编程方式添加了所有标题。我只需要页码。有没有其他方法可以得到特定段落的页码?我已经看过所有的屏幕放映了。但我只想找页码。 <w:r> <w:fldChar w:fldCharType="begin" /> </w:r> <w:r> <w:instrText xml:space="preserve"> PAGEREF _Toc481680509 \h </w:instrText> </w:r> <w:r> <w:fldChar w:fldCharType="separate" /> </w:r> <w:r> <w:t>2</w:t> </w:r> <w:r> <w:fldChar w:fldCharType="end" /> </w:r> 在该示例中,XML 2 "2“充当页码。那是硬编码 现在我的TOC在没有Pagenumber的情况下工作得很好。我还分析了默认的MS功能。第一次,页码是按字面意思给出的。

可以以编程方式将内容控件<w:sdt>作为<w:body>元素的子元素放置在文档中。

对于具有两个条目的简单TOC:

代码语言:javascript
运行
复制
<w:sdt>
    <w:sdtPr>
        <w:id w:val="429708664"/>
        <w:docPartObj>
            <w:docPartGallery w:val="Table of Contents"/>
            <w:docPartUnique/>
        </w:docPartObj>
    </w:sdtPr>
    <w:sdtContent>
        <w:p>
            <w:pPr>
                <w:pStyle w:val="TOCHeading"/>
            </w:pPr>
            <w:r>
                <w:t>Contents</w:t>
            </w:r>
        </w:p>
        <w:p>
            <w:pPr>
                <w:pStyle w:val="TOC1"/>
                <w:tabs>
                    <w:tab w:val="right" w:leader="dot" w:pos="9350"/>
                </w:tabs>
            </w:pPr>
            <w:r>
                <w:fldChar w:fldCharType="begin"/>
            </w:r>
            <w:r>
                <w:instrText xml:space="preserve"> TOC \o "1-3" \h \z \u </w:instrText>
            </w:r>
            <w:r>
                <w:fldChar w:fldCharType="separate"/>
            </w:r>
            <w:hyperlink w:anchor="_Toc481654079" w:history="1">
                <w:r>
                    <w:rPr>
                        <w:rStyle w:val="Hyperlink"/>
                    </w:rPr>
                    <w:t>Testing 1</w:t>
                </w:r>
                <w:r>
                    <w:tab/>
                </w:r>
                <w:r>
                    <w:fldChar w:fldCharType="begin"/>
                </w:r>
                <w:r>
                    <w:instrText xml:space="preserve"> PAGEREF _Toc481654079 \h </w:instrText>
                </w:r>
                <w:r>
                </w:r>
                <w:r>
                    <w:fldChar w:fldCharType="separate"/>
                </w:r>
                <w:r>
                    <w:t>0</w:t>
                </w:r>
                <w:r>
                    <w:fldChar w:fldCharType="end"/>
                </w:r>
            </w:hyperlink>
        </w:p>
        <w:p>
            <w:pPr>
                <w:pStyle w:val="TOC1"/>
                <w:tabs>
                    <w:tab w:val="right" w:leader="dot" w:pos="9350"/>
                </w:tabs>
            </w:pPr>
            <w:hyperlink w:anchor="_Toc481654080" w:history="1">
                <w:r>
                    <w:rPr>
                        <w:rStyle w:val="Hyperlink"/>                                
                    </w:rPr>
                    <w:t>Testing 2</w:t>
                </w:r>
                <w:r>
                    <w:tab/>
                </w:r>
                <w:r>
                    <w:fldChar w:fldCharType="begin"/>
                </w:r>
                <w:r>
                    <w:instrText xml:space="preserve"> PAGEREF _Toc481654080 \h </w:instrText>
                </w:r>
                <w:r>
                    <w:fldChar w:fldCharType="separate"/>
                </w:r>
                <w:r>
                    <w:t>0</w:t>
                </w:r>
                <w:r>
                    <w:fldChar w:fldCharType="end"/>
                </w:r>
            </w:hyperlink>
        </w:p>
        <w:p>
            <w:r>
                <w:fldChar w:fldCharType="end"/>
            </w:r>
        </w:p>
    </w:sdtContent>
</w:sdt>

注意PAGEREF字段代码的使用指向书签。还请注意后续的标记<w:t>0</w:t>。当打开文档并更新字段代码时,这个零将被书签为当前呈现的页码所取代。

每次对文档进行分页时,书签的确切位置可能会发生变化。

一旦将零替换为实例数字,您将在标记中观察到这些实例数字。但是,这些数字只是这些字段代码的最后呈现值。

在文档设置中,您可以提示用户在打开时更新字段代码,以便TOC数字能够准确地反映当前的屏幕呈现。为此,您的设置文件应该类似于:

代码语言:javascript
运行
复制
<w:settings ...namespaces ommitted...>
    <w:updateFields w:val="true"/>
    ...other settings ommitted...
</w:settings>

最后,您仍然需要使用字处理器来呈现OpenXML文档,但是您避免了计算页面位置的复杂性。

票数 6
EN

Stack Overflow用户

发布于 2020-12-07 08:48:39

获取当前页码

代码语言:javascript
运行
复制
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.Begin,
            });
            runs.Append(new FieldCode(@" PAGE \* MERGEFORMAT ")
            {
                Space = SpaceProcessingModeValues.Preserve
            });
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.Separate
            });
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.End
            });

获取总页码

代码语言:javascript
运行
复制
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.Begin,
            });
            runs.Append(new FieldCode(@" NUMPAGES \* MERGEFORMAT ")
            {
                Space = SpaceProcessingModeValues.Preserve
            });
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.Separate
            });
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.End
            });

完整代码

代码语言:javascript
运行
复制
            Run runs = new Run();
            runs.Append(new Text("第"));
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.Begin,
            });
            runs.Append(new FieldCode(@" PAGE \* MERGEFORMAT ")
            {
                Space = SpaceProcessingModeValues.Preserve
            });
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.Separate
            });
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.End
            });
            runs.Append(new Text("页/共"));
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.Begin,
            });
            runs.Append(new FieldCode(@" NUMPAGES \* MERGEFORMAT ")
            {
                Space = SpaceProcessingModeValues.Preserve
            });
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.Separate
            });
            runs.Append(new FieldChar
            {
                FieldCharType = FieldCharValues.End
            });
            runs.Append(new Text("页"));
            paragraph.Append(runs);

            footer1.Append(paragraph);

            part.Footer = footer1;

word显示在这里输入图像描述

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43700252

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档