目錄 (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 switches) 方法插入目錄。
- 使用 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);
// 檢查字段是否屬於目錄
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());
// 獲取此目錄項指向的位置
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;
// 這是一個列表,用於存儲在指定目錄中找到的節點。他們將被刪除
// 在這個方法的最後。
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 的 FieldStarts。
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 節點,我們就知道我們到了最後
// 當前的 TOC,我們可以在這裡停止。
if (currentNode->get_NodeType() == NodeType::FieldEnd)
{
System::SharedPtr<FieldEnd> fieldEnd = System::DynamicCast<FieldEnd>(currentNode);
if (fieldEnd->get_FieldType() == FieldType::FieldTOC)
{
isRemoving = false;
}
}
}
// 刪除在指定目錄中找到的所有節點。
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。如有任何疑問,請隨時通過我們的 免費支持論壇 與我們聯繫。