Word格式处理控件Aspose.Words for .NET教程——插入、修改、删除、提取目录

Aspose.Words for .NET是一种高级Word文档处理API,用于执行各种文档管理和操作任务。API支持生成,修改,转换,呈现和打印文档,而无需在跨平台应用程序中直接使用Microsoft Word。此外,API支持所有流行的Word处理文件格式,并允许将Word文档导出或转换为固定布局文件格式和最常用的图像/多媒体格式。

>>Aspose.Words for .NET已经更新至最新版,添加了新节点以处理多节结构化文档标签,改进了SmartArt冷渲染的性能,RevisionOptions类扩展了新的属性,
                                                   
                                                           Aspose.words最新下载

                               了解更多Aspose文档管理产品  Aspose技术交流群(761297826)


通常,需要使用包含目录(TOC)的文档。使用Aspose.Words,可以插入自己的目录或仅用几行代码即可完全重建文档中的现有目录。 本文概述了如何使用目录字段并演示了:

  • 如何插入全新的目录
  • 更新文档中的新目录或现有目录。
  • 指定开关以控制目录的格式和整体结构。
  • 如何修改目录的样式和外观。
  • 如何删除整个目录字段以及所有条目形成文档。

以编程方式插入目录

可以通过调用DocumentBuilder.InsertTableOfContents 方法将TOC(目录)字段插入当前位置的文档中。Word文档中的目录可以通过多种方式构建,并使用各种选项进行格式化。可以切换到该方法的字段切换,以控制表的构建方式和在文档中显示的方式。

在Microsoft Word中插入的目录中使用的默认开关是“ \ o” 1-3 \ h \ z \ u”。这些开关的说明以及受支持的开关列表可以在本文后面找到。可以使用该指南获取正确的开关,或者如果已经拥有包含想要的类似TOC的文档,则可以显示域代码(ALT + F9)并直接从该字段复制开关。下面的代码示例演示如何将目录字段插入文档中。

// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_WorkingWithDocument();
// Initialize document.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// Insert a table of contents at the beginning of the document.
builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");

// The newly inserted table of contents will be initially empty.
// It needs to be populated by updating the fields in the document.
doc.UpdateFields();
dataDir = dataDir + "DocumentBuilderInsertTOC_out.doc";
doc.Save(dataDir);

下面的代码示例演示如何使用标题样式作为条目将目录(TOC)插入文档。

Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);

// Insert a table of contents at the beginning of the document.
builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");

// Start the actual document content on the second page.
builder.InsertBreak(BreakType.PageBreak);

// Build a document with complex structure by applying different heading styles thus creating TOC entries.
builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;

builder.Writeln("Heading 1");

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;

builder.Writeln("Heading 1.1");
builder.Writeln("Heading 1.2");

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1;

builder.Writeln("Heading 2");
builder.Writeln("Heading 3");

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;

builder.Writeln("Heading 3.1");

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading3;

builder.Writeln("Heading 3.1.1");
builder.Writeln("Heading 3.1.2");
builder.Writeln("Heading 3.1.3");

builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2;

builder.Writeln("Heading 3.2");
builder.Writeln("Heading 3.3");

doc.UpdateFields();
dataDir = dataDir + "DocumentBuilderInsertTableOfContents_out.doc";
doc.Save(dataDir);

该代码演示了新目录插入到空白文档中。然后,使用DocumentBuilder类插入具有适当标题样式的一些示例内容格式,这些样式用于标记要包含在TOC中的内容。接下来的几行通过更新文档的字段和页面布局来填充目录。

更新目录

Aspose.Words允许您仅用几行代码即可完全更新TOC。在对文档进行更改后,可以执行此操作以填充新插入的目录或更新现有目录。 必须使用以下两种方法来更新文档中的TOC字段:

  1. Document.UpdateFields
  2. Document.UpdatePageLayout

请注意,这两个更新方法必须按该顺序调用。如果反转,将填充目录,但不会显示页码。可以更新任意数量的不同目录。这些方法将自动更新文档中找到的所有目录。下面的代码示例演示如何通过调用字段更新来完全重建文档中的TOC字段。

doc.UpdateFields();

对Document.UpdateFields的第一次调用将构建TOC,将填充所有文本条目,并且TOC几乎完成。唯一缺少的是现在用“?”显示的页码。 第二次调用Document.UpdatePageLayout将在内存中构建文档的布局。需要这样做以收集条目的页码。然后将从此调用中计算出的正确页码插入到目录中。

修改目录

TOC中条目的格式不使用标记条目的原始样式,而是使用等效的TOC样式来格式化每个级别。例如,TOC中的第一级使用TOC1样式设置格式,第二级使用TOC2样式设置,等等。这意味着要更改目录的外观,必须修改这些样式。在Aspose.Words中,这些样式由独立于语言环境的StyleIdentifier.TOC1到StyleIdentifier.TOC9表示,并且可以使用这些标识符从Document.Styles集合中检索。

一旦检索到适当的文档样式,就可以修改该样式的格式。对这些样式的任何更改将自动反映在文档的目录中。下面的示例更改在第一级TOC样式中使用的格式设置属性。

Document doc = new Document();            
// Retrieve the style used for the first level of the TOC and change the formatting of the style.
doc.Styles[StyleIdentifier.Toc1].Font.Bold = true;

还需要注意的是,标记为包含在TOC中的段落的任何直接格式(在段落本身上定义,而不是在样式中定义)都将被复制到TOC中的条目中。例如,如果标题1样式用于标记目录的内容,并且此样式具有粗体格式,而段落也具有直接应用于其的斜体格式。生成的TOC条目将不是粗体的,因为这是样式格式的一部分,但是由于它是直接在段落中设置的格式,因此将是斜体的。

使用为要修改的特定TOC级别检索到的Style类,还可以修改它们在文档中的显示方式。若要更改其显示方式,首先必须调用Style.ParagraphFormat来检索样式的段落格式。通过调用ParagraphFormat.TabStops可以从中检索制表位,并修改相应的制表位。使用相同的技术,选项卡本身可以一起移动或删除。下例显示了如何在TOC相关段落中修改右制表位的位置。

// The path to the documents directory.
string dataDir = RunExamples.GetDataDir_WorkingWithStyles();

string fileName = "Document.TableOfContents.doc";
// Open the document.
Document doc = new Document(dataDir + fileName);
        
// Iterate through all paragraphs in the document
foreach (Paragraph para in doc.GetChildNodes(NodeType.Paragraph, true))
{
    // Check if this paragraph is formatted using the TOC result based styles. This is any style between TOC and TOC9.
    if (para.ParagraphFormat.Style.StyleIdentifier >= StyleIdentifier.Toc1 && para.ParagraphFormat.Style.StyleIdentifier <= StyleIdentifier.Toc9) { // Get the first tab used in this paragraph, this should be the tab used to align the page numbers. TabStop tab = para.ParagraphFormat.TabStops[0]; // Remove the old tab from the collection. para.ParagraphFormat.TabStops.RemoveByPosition(tab.Position); // Insert a new tab using the same properties but at a modified position. // We could also change the separators used (dots) by passing a different Leader type para.ParagraphFormat.TabStops.Add(tab.Position - 50, tab.Alignment, tab.Leader); } } dataDir = dataDir + RunExamples.GetOutputFilePath(fileName); doc.Save(dataDir); 

从文档中删除目录

通过删除在TOC字段的FieldStart和FieldEnd节点之间找到的所有节点,可以从文档中删除目录。 下面的代码演示了这一点。TOC字段的删除比普通字段更简单,因为我们不跟踪嵌套字段。相反,我们检查FieldEnd节点的类型为FieldType.FieldTOC,这意味着我们遇到了当前TOC的结尾。在这种情况下,可以使用此技术而不必担心任何嵌套字段,因为我们可以假定任何格式正确的文档在另一个TOC字段内都不会完全嵌套的TOC字段。

首先,收集并存储每个TOC的FieldStart节点。然后枚举指定的TOC,以便访问和存储字段中的所有节点。然后将节点从文档中删除。下面的代码示例演示如何从文档中删除指定的目录。

public static void Run()
{
    
    // The path to the documents directory.
    string dataDir = RunExamples.GetDataDir_WorkingWithStyles();

    // Open a document which contains a TOC.
    Document doc = new Document(dataDir + "Document.TableOfContents.doc");

    // Remove the first table of contents from the document.
    RemoveTableOfContents(doc, 0);

    dataDir = dataDir + "Document.TableOfContentsRemoveToc_out.doc";
    // Save the output.
    doc.Save(dataDir);
    
    Console.WriteLine("\nSpecified TOC from a document removed successfully.\nFile saved at " + dataDir);
}
// Removes the specified table of contents field from the document.
//The document to remove the field from.///The zero-based index of the TOC to remove.public static void RemoveTableOfContents(Document doc, int index)
{
    // Store the FieldStart nodes of TOC fields in the document for quick access.
    ArrayList fieldStarts = new ArrayList();
    // This is a list to store the nodes found inside the specified TOC. They will be removed
    // At the end of this method.
    ArrayList nodeList = new ArrayList();

    foreach (FieldStart start in doc.GetChildNodes(NodeType.FieldStart, true))
    {
        if (start.FieldType == FieldType.FieldTOC)
        {
            // Add all FieldStarts which are of type FieldTOC.
            fieldStarts.Add(start);
        }
    }

    // Ensure the TOC specified by the passed index exists.
    if (index > fieldStarts.Count - 1)
        throw new ArgumentOutOfRangeException("TOC index is out of range");

    bool isRemoving = true;
    // Get the FieldStart of the specified TOC.
    Node currentNode = (Node)fieldStarts[index];

    while (isRemoving)
    {
        // It is safer to store these nodes and delete them all at once later.
        nodeList.Add(currentNode);
        currentNode = currentNode.NextPreOrder(doc);

        // Once we encounter a FieldEnd node of type FieldTOC then we know we are at the end
        // Of the current TOC and we can stop here.
        if (currentNode.NodeType == NodeType.FieldEnd)
        {
            FieldEnd fieldEnd = (FieldEnd)currentNode;
            if (fieldEnd.FieldType == FieldType.FieldTOC)
                isRemoving = false;
        }
    }

    // Remove all nodes found in the specified TOC.
    foreach (Node node in nodeList)
    {
        node.Remove();
    }
}

提取目录

如果要从任何Word文档中提取目录,则可以使用以下代码示例。

 // The path to the documents directory.
            string dataDir = RunExamples.GetDataDir_WorkingWithDocument();

            string fileName = "TOC.doc";
            Aspose.Words.Document doc = new Aspose.Words.Document(dataDir + fileName);

            foreach (Field field in doc.Range.Fields)
            {
                if (field.Type.Equals(Aspose.Words.Fields.FieldType.FieldHyperlink))
                {
                    FieldHyperlink hyperlink = (FieldHyperlink)field;
                    if (hyperlink.SubAddress != null && hyperlink.SubAddress.StartsWith("_Toc"))
                    {
                        Paragraph tocItem = (Paragraph)field.Start.GetAncestor(NodeType.Paragraph);
                        Console.WriteLine(tocItem.ToString(SaveFormat.Text).Trim());
                        Console.WriteLine("------------------");
                        if (tocItem != null)
                        {
                            Bookmark bm = doc.Range.Bookmarks[hyperlink.SubAddress];
                            // Get the location this TOC Item is pointing to
                            Paragraph pointer = (Paragraph)bm.BookmarkStart.GetAncestor(NodeType.Paragraph);
                            Console.WriteLine(pointer.ToString(SaveFormat.Text));
                        }
                    } // End If
                }// End If
            }// End Foreach
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值