使用目录
通常,您将处理包含目录(TOC)的文档。 使用Aspose.Words,您可以插入自己的目录,或者只需几行代码就可以完全重建文档中现有的目录。
本文概述了如何使用目录字段并演示:
- 如何插入一个全新的TOC。
- 更新文档中的新的或现有的TOCs。
- 指定开关以控制TOC的格式和整体结构。
- 如何修改目录的样式和外观.
- 如何从文档中删除整个
TOC
字段以及所有条目。
以编程方式插入目录
您可以通过调用InsertTableOfContents方法将TOC
(目录)字段插入到当前位置的文档中。
Word文档中的目录可以通过多种方式构建,并使用多种选项进行格式化。 传递给方法的字段开关控制了在文档中构建和显示表的方式。
在Microsoft Word中插入的TOC
中使用的默认开关是**"\o “1-3 \h \z \u”**。 这些交换机的描述以及支持的交换机的列表可以在本文后面找到。 您可以使用该指南获得正确的开关,或者如果您已经有一个包含类似TOC
的文档,您可以显示字段代码(*ALT+F9*)并直接从字段复制开关。
下面的代码示例演示如何将目录字段插入到文档中:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
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(); | |
doc.save(dataDir + "InsertATableOfContentsField_out.docx"); |
下面的代码示例演示如何使用标题样式作为条目将目录(TOC)插入到文档中:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(); | |
// Create a document builder to insert content with into 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.PAGE_BREAK); | |
// Build a document with complex structure by applying different heading styles thus creating TOC entries. | |
builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); | |
builder.writeln("Heading 1"); | |
builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); | |
builder.writeln("Heading 1.1"); | |
builder.writeln("Heading 1.2"); | |
builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_1); | |
builder.writeln("Heading 2"); | |
builder.writeln("Heading 3"); | |
builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); | |
builder.writeln("Heading 3.1"); | |
builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_3); | |
builder.writeln("Heading 3.1.1"); | |
builder.writeln("Heading 3.1.2"); | |
builder.writeln("Heading 3.1.3"); | |
builder.getParagraphFormat().setStyleIdentifier(StyleIdentifier.HEADING_2); | |
builder.writeln("Heading 3.2"); | |
builder.writeln("Heading 3.3"); | |
// Call the method below to update the TOC. | |
doc.updateFields(); | |
doc.save(dataDir + "InsertATableOfContentsUsingHeadingStyles_out.docx"); |
该代码演示将新的目录插入到空白文档中。 然后使用DocumentBuilder类插入一些具有适当标题样式的示例内容格式,这些标题样式用于标记要包含在TOC中的内容。 接下来的行通过更新文档的字段和页面布局来填充TOC
。
TOC
字段,但没有可见的内容。 这是因为TOC
字段已插入,但在文档中更新之前尚未填充。 有关这方面的进一步信息将在下一节中讨论。
更新目录
Aspose.Words允许您只用几行代码就可以完全更新TOC
。 这样做可以填充新插入的TOC
,或者在对文档进行更改后更新现有的TOC
。
必须使用以下两种方法来更新文档中的TOC
字段:
请注意,需要按该顺序调用这两个更新方法。 如果反转,将填充目录,但不会显示页码。 可以更新任意数量的不同TOCs。 这些方法将自动更新文档中找到的所有TOCs。
下面的代码示例演示如何通过调用字段更新来完全重建文档中的TOC
字段:
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
doc.updateFields(); |
对Document.updateFields()的第一次调用将构建TOC
,填充所有文本条目,并且TOC
看起来几乎完成。 唯一缺少的是现在用"?“显示的页码。
对Document.updatePageLayout()的第二次调用将在内存中构建文档的布局。 这需要做收集条目的页码。 然后将从该调用计算出的正确页码插入TOC中。
使用开关控制目录行为
与任何其他字段一样,TOC
字段可以接受在控制内容列表构建方式的字段代码中定义的开关。 某些开关用于控制包含哪些条目以及在什么级别,而其他开关用于控制TOC的外观。 开关可以组合在一起,以允许产生一个复杂的目录。
默认情况下,在文档中插入默认TOC
时包含上述这些开关。 没有开关的TOC
将包括内置标题样式中的内容(就像设置了\O开关一样)。
下面列出了Aspose.Words支持的可用TOC
开关,并详细描述了它们的用途。 它们可以根据类型分为不同的部分。 第一部分中的开关定义要包含在TOC
中的内容,第二部分中的开关控制TOC的外观。
如果此处未列出交换机,则当前不支持该交换机。 所有交换机将在未来的版本中支持。 我们正在为每个版本增加进一步的支持。
进入标记开关
开关,开关 | 资料描述 |
---|---|
Heading Styles (\O开关) |
此开关定义了
|
Outline Levels (\U开关) |
每个段落都可以在段落选项下定义大纲级别。
请注意,内置标题样式(如Heading 1)在样式设置中必须设置大纲级别。
|
Custom Styles (\T开关) |
此开关将允许在收集要在TOC中使用的条目时使用自定义样式。 这通常与\O开关一起使用,以包括自定义样式以及TOC中的内置标题样式。
将使用CustomHeading1样式的内容作为 |
使用TC字段 (\F和\L开关) |
在旧版本的Microsoft Word中,构建 这些字段可以像任何其他字段一样在任何位置插入到文档中,并由
将只包括TC字段,如
-\F-上面解释过。 –\L-定义此TC字段将出现在 - |
外观相关开关
开关,开关 | 资料描述 |
---|---|
Omit Page Numbers (\N开关) |
此开关用于隐藏TOC的某些级别的页码。 例如,可以定义
第3级和第4级条目上的页码将与领导者点(如果有的话)一起隐藏。 要仅指定一个级别,仍应使用范围,例如,“1-1"将仅排除第一级的页码。 |
插入为超链接 (\H开关) |
此开关指定 |
Set Separator Character (\P开关) |
此开关允许在TOC中轻松更改分隔条目标题和页码的内容。 要使用的分隔符应在此开关后指定,并用语音标记括起来。 |
Preserve Tab Entries (\W开关) |
使用此开关将指定具有制表符的任何条目,例如,在行尾具有制表符的标题,在填充TOC时将保留为适当的制表符。 这意味着制表符的功能将出现在 |
Preserve New Line Entries (\X开关) |
与上面的开关类似,此开关指定跨越多行的标题(使用换行符,而不是单独的段落)将保留为生成的TOC中的标题。 例如,要跨多行分布的标题可以使用新行字符(Ctrl+Enter或 |
插入TC字段
您可以通过调用DocumentBuilder.InsertField
方法并将字段名称指定为"TC"以及所需的任何开关,在DocumentBuilder
的当前位置插入新的TC字段。
下面的代码示例演示如何使用DocumentBuilder将TC
字段插入到文档中。
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
Document doc = new Document(); | |
// Create a document builder to insert content with. | |
DocumentBuilder builder = new DocumentBuilder(doc); | |
// Insert a TC field at the current document builder position. | |
builder.insertField("TC \"Entry Text\" \\f t"); |
通常为TOC
指定特定的文本行,并用TC
字段标记。 在MSWord中执行此操作的简单方法是突出显示文本并按ALT+SHIFT+O。 这会使用所选文本自动创建TC
字段。 同样的技术可以通过代码来完成。 下面的代码将找到与输入匹配的文本,并在与文本相同的位置插入TC
字段。 该代码基于文章中使用的相同技术。 下面的代码示例演示如何在文档中的文本中查找并插入TC
字段。
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
class InsertTCFieldHandler implements IReplacingCallback { | |
// Store the text and switches to be used for the TC fields. | |
private String mFieldText; | |
private String mFieldSwitches; | |
/** | |
* The switches to use for each TC field. Can be an empty string or null. | |
*/ | |
public InsertTCFieldHandler(String switches) throws Exception { | |
this(null, switches); | |
} | |
/** | |
* The display text and the switches to use for each TC field. Display text | |
* Can be an empty string or null. | |
*/ | |
public InsertTCFieldHandler(String text, String switches) throws Exception { | |
mFieldText = text; | |
mFieldSwitches = switches; | |
} | |
public int replacing(ReplacingArgs args) throws Exception { | |
// Create a builder to insert the field. | |
DocumentBuilder builder = new DocumentBuilder((Document) args.getMatchNode().getDocument()); | |
// Move to the first node of the match. | |
builder.moveTo(args.getMatchNode()); | |
// If the user specified text to be used in the field as display text then use that, otherwise use the | |
// match string as the display text. | |
String insertText; | |
if (!(mFieldText == null || "".equals(mFieldText))) | |
insertText = mFieldText; | |
else | |
insertText = args.getMatch().group(); | |
// Insert the TC field before this node using the specified string as the display text and user defined switches. | |
builder.insertField(java.text.MessageFormat.format("TC \"{0}\" {1}", insertText, mFieldSwitches)); | |
// We have done what we want so skip replacement. | |
return ReplaceAction.SKIP; | |
} | |
} |
修改目录
更改样式的格式
TOC
中的条目格式不使用标记条目的原始样式,而是使用等效的TOC
样式对每个级别进行格式设置。 例如,TOC
中的第一级用TOC1样式格式化,第二级用TOC2样式格式化等等。 这意味着要更改TOC
的外观,必须修改这些样式。 在Aspose.Words中,这些样式由与语言环境无关的StyleIdentifier.TOC1
到StyleIdentifier.TOC9
表示,可以使用这些标识符从Document.Styles
集合中检索。
一旦检索到文档的适当样式,就可以修改此样式的格式。 对这些样式的任何更改都将自动反映在文档中的TOCs中。
下面的代码示例更改第一级TOC
样式中使用的格式化属性。
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
public static void changeAFormattingPropertyUsedInFirstLevelTOCStyle() throws Exception { | |
Document doc = new Document(); | |
// Retrieve the style used for the first level of the TOC and change the formatting of the style. | |
doc.getStyles().getByStyleIdentifier(StyleIdentifier.TOC_1).getFont().setBold(true); | |
} |
还需要注意的是,标记为包含在TOC
中的段落(在段落本身上定义而不是在样式中定义)的任何直接格式都将复制到TOC中的条目中。 例如,如果Heading 1样式用于标记TOC
的内容,并且此样式具有粗体格式,而段落也直接应用斜体格式。 生成的TOC
条目不会是粗体,因为这是样式格式的一部分,但是它将是斜体,因为这是直接在段落上格式化的。
您还可以控制每个条目和页码之间使用的分隔符的格式。 默认情况下,这是一条虚线,使用制表符和靠近右边距的右制表位排列在页面编号上。
使用为要修改的特定TOC
级别检索的Style
类,还可以修改这些在文档中的显示方式。
要更改它的显示方式,首先必须调用Style.ParagraphFormat
来检索样式的段落格式。 由此,可以通过调用ParagraphFormat.TabStops
检索选项卡停止,并修改相应的选项卡停止。 使用相同的技术,选项卡本身可以完全移动或删除。
下面的代码示例演示如何在TOC
相关段落中修改右制表符停止的位置。
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
public static void modifyPositionOfRightTabStopInTOC() throws Exception { | |
Document doc = new Document(dataDir + "Field.TableOfContents.doc"); | |
// Iterate through all paragraphs in the document | |
for (Paragraph para : (Iterable<Paragraph>) 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.getParagraphFormat().getStyle().getStyleIdentifier() >= StyleIdentifier.TOC_1 && para.getParagraphFormat().getStyle().getStyleIdentifier() <= StyleIdentifier.TOC_9) { | |
// Get the first tab used in this paragraph, this should be the tab used to align the page numbers. | |
TabStop tab = para.getParagraphFormat().getTabStops().get(0); | |
// Remove the old tab from the collection. | |
para.getParagraphFormat().getTabStops().removeByPosition(tab.getPosition()); | |
// 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.getParagraphFormat().getTabStops().add(tab.getPosition() - 50, tab.getAlignment(), tab.getLeader()); | |
} | |
} | |
doc.save(dataDir + "Field.TableOfContentsTabStops_Out.doc"); | |
} |
从文档中删除目录
通过删除在TOC
字段的FieldStart
和FieldEnd节点之间找到的所有节点,可以从文档中删除目录。
下面的代码演示了这一点。 删除TOC
字段比普通字段简单,因为我们不跟踪嵌套字段。 相反,我们检查FieldEnd
节点的类型为FieldType.FieldTOC
,这意味着我们遇到了当前TOC的结尾。 这种技术可以在这种情况下使用,而不必担心任何嵌套字段,因为我们可以假设任何正确形成的文档在另一个TOC
字段中没有完全嵌套的TOC
字段。
首先收集并存储每个TOC
的FieldStart
节点。 然后枚举指定的TOC
,以便访问并存储字段中的所有节点。 然后从文档中删除节点。 下面的代码示例演示如何从文档中删除指定的TOC
。
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
// 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); | |
// Save the output. | |
doc.save(dataDir + "Document.TableOfContentsRemoveToc_Out.doc"); |
摘录目录
如果要从任何Word文档中提取目录,可以使用以下代码示例。
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java | |
// The path to the documents directory. | |
String dataDir = Utils.getSharedDataDir(ExtractTableOfContents.class) + "TableOfContents/"; | |
String fileName = "TOC.doc"; | |
Document doc = new Document(dataDir + fileName); | |
for (Field field : (Iterable<Field>)doc.getRange().getFields()) | |
{ | |
if (field.getType() == FieldType.FIELD_HYPERLINK) | |
{ | |
FieldHyperlink hyperlink = (FieldHyperlink)field; | |
if (hyperlink.getSubAddress() != null && hyperlink.getSubAddress().startsWith("_Toc")) | |
{ | |
Paragraph tocItem = (Paragraph)field.getStart().getAncestor(NodeType.PARAGRAPH); | |
System.out.println(tocItem.toString(SaveFormat.TEXT).trim()); | |
System.out.println("------------------"); | |
if (tocItem != null) | |
{ | |
Bookmark bm = doc.getRange().getBookmarks().get(hyperlink.getSubAddress()); | |
// Get the location this TOC Item is pointing to | |
Paragraph pointer = (Paragraph)bm.getBookmarkStart().getAncestor(NodeType.PARAGRAPH); | |
System.out.println(pointer.toString(SaveFormat.TEXT)); | |
} | |
} // End If | |
}// End If | |
}// End Foreach |