Last active
May 11, 2021 01:09
-
-
Save aspose-com-gists/74023eecde943738bd5d1a406c64e638 to your computer and use it in GitHub Desktop.
Working with Table of Contents in Word Documents using C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Working with Table of Contents in Word Documents using C++ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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