Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aspose-com-gists/74023eecde943738bd5d1a406c64e638 to your computer and use it in GitHub Desktop.
Save aspose-com-gists/74023eecde943738bd5d1a406c64e638 to your computer and use it in GitHub Desktop.
Working with Table of Contents in Word Documents using C++
Working with Table of Contents in Word Documents using C++
// Source and output directory paths.
System::String sourceDataDir = u"SourceDirectory\\";
System::String outputDataDir = u"OutputDirectory\\";
// Load the Word file
System::SharedPtr<Document> doc = System::MakeObject<Document>(sourceDataDir + u"Sample 5.docx");
// Create an instance of the DocumentBuilder class
System::SharedPtr<DocumentBuilder> builder = System::MakeObject<DocumentBuilder>(doc);
// Insert a table of contents at the beginning of the document.
builder->InsertTableOfContents(u"\\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();
// Output file path
System::String outputPath = outputDataDir + u"AddTOC.docx";
// Save the Word file
doc->Save(outputPath);
// Source direvctory
System::String inputDataDir = u"SourceDirectory\\";
// Load the Word file
System::SharedPtr<Document> doc = System::MakeObject<Document>(inputDataDir + u"SampleTOC.docx");
// Loop through the fields
for (System::SharedPtr<Field> field : System::IterateOver(doc->get_Range()->get_Fields()))
{
// Get FieldHyperlink fields
if (field->get_Type() == FieldType::FieldHyperlink)
{
System::SharedPtr<FieldHyperlink> hyperlink = System::DynamicCast<FieldHyperlink>(field);
// Check if field belongs to 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());
// Get the location this TOC Item is pointing to
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;
}
}
}
}
void RemoveTableOfContents(const System::SharedPtr<Document>& doc, int32_t index)
{
// Store the FieldStart nodes of TOC fields in the document for quick access.
std::vector<System::SharedPtr<FieldStart>> fieldStarts;
// This is a list to store the nodes found inside the specified TOC. They will be removed
// at the end of this method.
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)
{
// Add all FieldStarts which are of type FieldTOC.
fieldStarts.push_back(start);
}
}
// Ensure that the TOC specified by the passed index exists.
if (index > fieldStarts.size() - 1)
{
throw System::ArgumentOutOfRangeException(u"TOC index is out of range");
}
bool isRemoving = true;
// Get the FieldStart of the specified TOC.
System::SharedPtr<Node> currentNode = fieldStarts[index];
while (isRemoving)
{
// It is safer to store these nodes and delete them all at once later.
nodeList.push_back(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->get_NodeType() == NodeType::FieldEnd)
{
System::SharedPtr<FieldEnd> fieldEnd = System::DynamicCast<FieldEnd>(currentNode);
if (fieldEnd->get_FieldType() == FieldType::FieldTOC)
{
isRemoving = false;
}
}
}
// Remove all nodes found in the specified TOC.
for (System::SharedPtr<Node> node : nodeList)
{
node->Remove();
}
}
int main()
{
// Source and output directory paths.
System::String sourceDataDir = u"SourceDirectory\\";
System::String outputDataDir = u"OutputDirectory\\";
// Open a Word document
System::SharedPtr<Document> doc = System::MakeObject<Document>(sourceDataDir + u"SampleTOC.docx");
// Remove the first table of contents from the document.
RemoveTableOfContents(doc, 0);
// Output file path
System::String outputPath = outputDataDir + u"RemoveTOC.docx";
// Save the Word file
doc->Save(outputPath);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment