目次(TOC)は、Word文書の重要な部分です。ドキュメントのコンテンツの概要を提供し、目的のセクションにすばやく移動できるようにします。プログラムでWord文書から目次を追加、抽出、更新、または削除する必要があるシナリオに遭遇するかもしれません。そのために、この記事では、C++を使用してWordファイルの目次を操作する方法を説明します。

Word文書の目次を操作するためのC++API

Aspose.Words for C++はネイティブC++ライブラリであり、Microsoft Wordドキュメントの作成、読み取り、変更、および変換を行うことができます。さらに、Wordファイルの目次の操作もサポートしています。 APIは、NuGetからインストールするか、ダウンロードセクションから直接ダウンロードできます。

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文書から目次を抽出する手順です。

  • Documentクラスを使用してWordファイルをロードします。
  • Document->get->Range()->get->Fields()メソッドを使用してフィールドを取得し、ループします。
  • フィールドのタイプが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文書から目次を削除する手順です。

次のサンプルコードは、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);
		}
	}

	// 渡されたインデックスで指定された目次が存在することを確認します。
	if (index > fieldStarts.size() - 1)
	{
		throw System::ArgumentOutOfRangeException(u"TOC index is out of range");
	}

	bool isRemoving = true;

	// 指定された目次の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;
			}
		}
	}

	// 指定された目次で見つかったすべてのノードを削除します。
	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の詳細を調べることができます。ご不明な点がございましたら、無料サポートフォーラムまでお気軽にお問い合わせください。

関連項目