Word格式處理控件Aspose.Words for .NET教程——插入、修改、刪除、提取目錄
Aspose.Words for .NET是一種高級Word文檔處理API,用于執(zhí)行各種文檔管理和操作任務(wù)。API支持生成,修改,轉(zhuǎn)換,呈現(xiàn)和打印文檔,而無需在跨平臺應(yīng)用程序中直接使用Microsoft Word。此外,API支持所有流行的Word處理文件格式,并允許將Word文檔導(dǎo)出或轉(zhuǎn)換為固定布局文件格式和最常用的圖像/多媒體格式。
>>Aspose.Words for .NET已經(jīng)更新至v20.7,添加了新節(jié)點以處理多節(jié)結(jié)構(gòu)化文檔標(biāo)簽,改進了SmartArt冷渲染的性能,RevisionOptions類擴展了新的屬性,點擊下載體驗
通常,需要使用包含目錄(TOC)的文檔。使用Aspose.Words,可以插入自己的目錄或僅用幾行代碼即可完全重建文檔中的現(xiàn)有目錄。 本文概述了如何使用目錄字段并演示了:
- 如何插入全新的目錄
- 更新文檔中的新目錄或現(xiàn)有目錄。
- 指定開關(guān)以控制目錄的格式和整體結(jié)構(gòu)。
- 如何修改目錄的樣式和外觀。
- 如何刪除整個目錄字段以及所有條目形成文檔。
以編程方式插入目錄
可以通過調(diào)用DocumentBuilder.InsertTableOfContents 方法將TOC(目錄)字段插入當(dāng)前位置的文檔中。Word文檔中的目錄可以通過多種方式構(gòu)建,并使用各種選項進行格式化??梢郧袚Q到該方法的字段切換,以控制表的構(gòu)建方式和在文檔中顯示的方式。
在Microsoft Word中插入的目錄中使用的默認開關(guān)是“ \ o” 1-3 \ h \ z \ u”。這些開關(guān)的說明以及受支持的開關(guān)列表可以在本文后面找到??梢允褂迷撝改汐@取正確的開關(guān),或者如果已經(jīng)擁有包含想要的類似TOC的文檔,則可以顯示域代碼(ALT + F9)并直接從該字段復(fù)制開關(guān)。下面的代碼示例演示如何將目錄字段插入文檔中。
// 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);
下面的代碼示例演示如何使用標(biāo)題樣式作為條目將目錄(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類插入具有適當(dāng)標(biāo)題樣式的一些示例內(nèi)容格式,這些樣式用于標(biāo)記要包含在TOC中的內(nèi)容。接下來的幾行通過更新文檔的字段和頁面布局來填充目錄。
更新目錄
Aspose.Words允許您僅用幾行代碼即可完全更新TOC。在對文檔進行更改后,可以執(zhí)行此操作以填充新插入的目錄或更新現(xiàn)有目錄。 必須使用以下兩種方法來更新文檔中的TOC字段:
- Document.UpdateFields
- Document.UpdatePageLayout
請注意,這兩個更新方法必須按該順序調(diào)用。如果反轉(zhuǎn),將填充目錄,但不會顯示頁碼??梢愿氯我鈹?shù)量的不同目錄。這些方法將自動更新文檔中找到的所有目錄。下面的代碼示例演示如何通過調(diào)用字段更新來完全重建文檔中的TOC字段。
doc.UpdateFields();
對Document.UpdateFields的第一次調(diào)用將構(gòu)建TOC,將填充所有文本條目,并且TOC幾乎完成。唯一缺少的是現(xiàn)在用“?”顯示的頁碼。 第二次調(diào)用Document.UpdatePageLayout將在內(nèi)存中構(gòu)建文檔的布局。需要這樣做以收集條目的頁碼。然后將從此調(diào)用中計算出的正確頁碼插入到目錄中。
修改目錄
TOC中條目的格式不使用標(biāo)記條目的原始樣式,而是使用等效的TOC樣式來格式化每個級別。例如,TOC中的第一級使用TOC1樣式設(shè)置格式,第二級使用TOC2樣式設(shè)置,等等。這意味著要更改目錄的外觀,必須修改這些樣式。在Aspose.Words中,這些樣式由獨立于語言環(huán)境的StyleIdentifier.TOC1到StyleIdentifier.TOC9表示,并且可以使用這些標(biāo)識符從Document.Styles集合中檢索。
一旦檢索到適當(dāng)?shù)奈臋n樣式,就可以修改該樣式的格式。對這些樣式的任何更改將自動反映在文檔的目錄中。下面的示例更改在第一級TOC樣式中使用的格式設(shè)置屬性。
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;
還需要注意的是,標(biāo)記為包含在TOC中的段落的任何直接格式(在段落本身上定義,而不是在樣式中定義)都將被復(fù)制到TOC中的條目中。例如,如果標(biāo)題1樣式用于標(biāo)記目錄的內(nèi)容,并且此樣式具有粗體格式,而段落也具有直接應(yīng)用于其的斜體格式。生成的TOC條目將不是粗體的,因為這是樣式格式的一部分,但是由于它是直接在段落中設(shè)置的格式,因此將是斜體的。
使用為要修改的特定TOC級別檢索到的Style類,還可以修改它們在文檔中的顯示方式。若要更改其顯示方式,首先必須調(diào)用Style.ParagraphFormat來檢索樣式的段落格式。通過調(diào)用ParagraphFormat.TabStops可以從中檢索制表位,并修改相應(yīng)的制表位。使用相同的技術(shù),選項卡本身可以一起移動或刪除。下例顯示了如何在TOC相關(guān)段落中修改右制表位的位置。
// 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節(jié)點之間找到的所有節(jié)點,可以從文檔中刪除目錄。 下面的代碼演示了這一點。TOC字段的刪除比普通字段更簡單,因為我們不跟蹤嵌套字段。相反,我們檢查FieldEnd節(jié)點的類型為FieldType.FieldTOC,這意味著我們遇到了當(dāng)前TOC的結(jié)尾。在這種情況下,可以使用此技術(shù)而不必擔(dān)心任何嵌套字段,因為我們可以假定任何格式正確的文檔在另一個TOC字段內(nèi)都不會完全嵌套的TOC字段。
首先,收集并存儲每個TOC的FieldStart節(jié)點。然后枚舉指定的TOC,以便訪問和存儲字段中的所有節(jié)點。然后將節(jié)點從文檔中刪除。下面的代碼示例演示如何從文檔中刪除指定的目錄。
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
還想要更多嗎?您可以點擊閱讀【2020 · Aspose最新資源整合】,查找需要的教程資源。如果您有任何疑問或需求,請隨時加入Aspose技術(shù)交流群(642018183),我們很高興為您提供查詢和咨詢。