目录 (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 文档中添加目录的步骤。
- 使用 Document 类加载 Word 文件。
- 使用之前创建的 Document 对象创建 DocumentBuilder 类的实例。
- 使用 DocumentBuilder->InsertTableOfContents(System::String 开关) 方法插入目录。
- 使用 Document->UpdateFields() 方法填充目录。
- 使用 Document->Save(System::String fileName) 方法保存 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 文档中提取目录的步骤。
- 使用 Document 类加载 Word 文件。
- 使用 Document->getRange()->getFields() 方法检索字段并遍历它们。
- 检查字段是否为 FieldType::FieldHyperlink 类型。
- 检查该字段是否属于目录。
- 检索并打印字段信息。
以下示例代码演示了如何使用 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 文档中删除目录的步骤。
- 使用 Document 类加载 Word 文件。
- 检索并存储 FieldStart 节点的列表。
- 遍历节点,直到到达类型为 NodeType::FieldEnd 的节点,该节点指定目录的结尾。
- 使用 Node->Remove() 方法删除目录。
- 使用 Document->Save(System::String fileName) 方法保存 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。如有任何问题,请随时通过我们的 免费支持论坛 与我们联系。