目录 (TOC) 是 Word 文档的重要组成部分。它提供文档内容的概述,并允许您快速导航到所需的部分。您可能会发现自己需要以编程方式从 Word 文档中添加、提取、更新或删除目录。为此,本文将教您如何使用 C++ 处理 Word 文件中的目录。

用于处理 Word 文档中的目录的 C++ API

Aspose.Words for C++ 是一个本地 C++ 库,允许您创建、读取、修改和转换 Microsoft Word 文档。此外,它还支持处理 Word 文件中的目录。您可以通过 NuGet 安装 API,也可以直接从 下载 部分下载。

PM> Install-Package Aspose.Words.Cpp

在 Word 文档中添加目录

以下是在 Word 文档中添加目录的步骤。

以下示例代码展示了如何使用 C++ 在 Word 文档中添加目录。

// 源和输出目录路径。
System::String sourceDataDir = u"SourceDirectory\\";
System::String outputDataDir = u"OutputDirectory\\";

// 加载 Word 文件
System::SharedPtr<Document> doc = System::MakeObject<Document>(sourceDataDir + u"Sample 5.docx");

// 创建 DocumentBuilder 类的实例
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(doc);

// 在文档开头插入目录。
builder->InsertTableOfContents(u"\\o \"1-3\" \\h \\z \\u");

// 新插入的目录最初是空的。
// 它需要通过更新文档中的字段来填充。
doc->UpdateFields();

// 输出文件路径
System::String outputPath = outputDataDir + u"AddTOC.docx";

// 保存 Word 文件
doc->Save(outputPath);
输出包含目录的 Word 文件

输出包含目录的 Word 文件

从 Word 文档中提取目录

以下是从 Word 文档中提取目录的步骤。

以下示例代码演示了如何使用 C++ 从 Word 文档中提取目录。

// 源目录
System::String inputDataDir = u"SourceDirectory\\";

// 加载 Word 文件
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"SampleTOC.docx");

// 循环遍历字段
for (System::SharedPtr<Field> field : System::IterateOver(doc->get_Range()->get_Fields()))
{
	// 获取 FieldHyperlink 字段
	if (field->get_Type() == FieldType::FieldHyperlink)
	{
		System::SharedPtr<FieldHyperlink> hyperlink = System::DynamicCast<FieldHyperlink>(field);

		// 检查字段是否属于 TOC
		if (hyperlink->get_SubAddress() != nullptr && hyperlink->get_SubAddress().StartsWith(u"_Toc"))
		{
			System::SharedPtr<Paragraph> tocItem = System::DynamicCast<Paragraph>(field->get_FieldStart()->GetAncestor(NodeType::Paragraph));
			std::cout << System::StaticCast<Node>(tocItem)->ToString(SaveFormat::Text).Trim().ToUtf8String() << std::endl;
			std::cout << "------------------" << std::endl;
			if (tocItem != nullptr)
			{
				System::SharedPtr<Bookmark> bm = doc->get_Range()->get_Bookmarks()->idx_get(hyperlink->get_SubAddress());

				// 获取此 TOC 项指向的位置
				System::SharedPtr<Paragraph> pointer = System::DynamicCast<Paragraph>(bm->get_BookmarkStart()->GetAncestor(NodeType::Paragraph));
				std::cout << System::StaticCast<Node>(pointer)->ToString(SaveFormat::Text).ToUtf8String() << std::endl;
			}
		}
	}
}

更新 Word 文档中的目录

如果文档的内容已经更新,并且您需要在目录中反映这些更改,您只需加载 Word 文件并调用 Document->UpdateFields() 方法。该方法会根据修改后的内容更新目录。在此之后,保存更新的 Word 文档。

从 Word 文档中删除目录

以下是从 Word 文档中删除目录的步骤。

以下示例代码显示如何使用 C++ 从 Word 文档中删除目录。

void RemoveTableOfContents(const System::SharedPtr<Document>& doc, int32_t index)
{
	// 将 TOC 字段的 FieldStart 节点存储在文档中以便快速访问。
	std::vector<System::SharedPtr<FieldStart>> fieldStarts;
	// 这是一个列表,用于存储在指定 TOC 中找到的节点。他们将被删除
	// 在这个方法的最后。
	std::vector<System::SharedPtr<Node>> nodeList;

	for (System::SharedPtr<FieldStart> start : System::IterateOver<System::SharedPtr<FieldStart>>(doc->GetChildNodes(NodeType::FieldStart, true)))
	{
		if (start->get_FieldType() == FieldType::FieldTOC)
		{
			// 添加所有 FieldTOC 类型的 FieldStart。
			fieldStarts.push_back(start);
		}
	}

	// 确保传递的索引指定的 TOC 存在。
	if (index > fieldStarts.size() - 1)
	{
		throw System::ArgumentOutOfRangeException(u"TOC index is out of range");
	}

	bool isRemoving = true;

	// 获取指定 TOC 的 FieldStart。
	System::SharedPtr<Node> currentNode = fieldStarts[index];

	while (isRemoving)
	{
		// 存储这些节点并稍后将它们全部删除会更安全。
		nodeList.push_back(currentNode);
		currentNode = currentNode->NextPreOrder(doc);

		// 一旦我们遇到 FieldTOC 类型的 FieldEnd 节点,我们就知道我们在最后
		// 的当前目录,我们可以在这里停下来。
		if (currentNode->get_NodeType() == NodeType::FieldEnd)
		{
			System::SharedPtr<FieldEnd> fieldEnd = System::DynamicCast<FieldEnd>(currentNode);
			if (fieldEnd->get_FieldType() == FieldType::FieldTOC)
			{
				isRemoving = false;
			}
		}
	}

	// 删除在指定 TOC 中找到的所有节点。
	for (System::SharedPtr<Node> node : nodeList)
	{
		node->Remove();
	}
}

int main()
{
	// 源和输出目录路径。
	System::String sourceDataDir = u"SourceDirectory\\";
	System::String outputDataDir = u"OutputDirectory\\";

	// 打开一个 Word 文档
	System::SharedPtr<Document> doc = System::MakeObject<Document>(sourceDataDir + u"SampleTOC.docx");

	// 从文档中删除第一个目录。
	RemoveTableOfContents(doc, 0);

	// 输出文件路径
	System::String outputPath = outputDataDir + u"RemoveTOC.docx";

	// 保存 Word 文件
	doc->Save(outputPath);
}

获得免费许可证

您可以通过请求 免费的临时许可证 来试用该 API,而不受评估限制。

结论

在本文中,您学习了如何使用 C++ 处理 Word 文档中的目录。您已经看到了从 Word 文档中添加、提取、更新和删除目录所需的步骤和示例代码。 Aspose.Words for C++ 为处理 Word 文件提供了许多附加功能。您可以通过访问 官方文档 来详细探索 API。如有任何问题,请随时通过我们的 免费支持论坛 与我们联系。

也可以看看