0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

C++ で Word 文書内のテキストを検索しハイライト表示する方法

0
Posted at

Word 文書内のテキストを検索し、該当箇所をハイライト表示する処理は、文書のレビューや編集の際によく行われる操作の一つです。特定のキーワードを目立たせたい場合や、文書内の重要な箇所を視覚的にマークしたい場合に用いられます。C++ でこの処理を自動化できれば、大量の文書を扱う際の手間を省くことができます。

本記事では、Spire.Doc for C++ を使用して、C++ で Word 文書内のテキストを検索し、該当箇所の背景色を変更する(ハイライトする)方法を紹介します。Spire.Doc for C++ は、Microsoft Office がインストールされていない環境でも Word 文書の作成・編集・変換を行える、独立した C++ ライブラリです。

環境構築

Spire.Doc for C++ をプロジェクトに導入する方法は以下の2つです。

  1. NuGet 経由でのインストール: Visual Studio の「NuGet パッケージの管理」から spire.doc.cpp を検索してインストールします。
  2. 手動での追加: 公式サイトからパッケージをダウンロードし、ヘッダーファイルとライブラリファイルをプロジェクトに追加します。

導入後は、以下のヘッダーファイルをインクルードします。

#include "Spire.Doc.o.h"

単一のテキストを検索しハイライトする

まず、特定のテキストを検索し、最初に見つかったインスタンスのみをハイライトする基本的な方法です。FindString メソッドでテキストを検索し、TextRange オブジェクトの GetCharacterFormat()->SetHighlightColor() で背景色を設定します。

#include "Spire.Doc.o.h"

using namespace Spire::Doc;
using namespace std;

int main()
{
    // Documentオブジェクトを作成し、Word文書をロード
    intrusive_ptr<Document> document = new Document();
    document->LoadFromFile(L"Input.docx");

    // 特定のテキストを検索(最初の1件)
    intrusive_ptr<TextSelection> selection = document->FindString(L"重要", false, true);

    // 見つかったテキストを取得
    intrusive_ptr<TextRange> range = selection->GetAsOneRange();

    // 背景色を黄色に設定(ハイライト)
    range->GetCharacterFormat()->SetHighlightColor(Color::GetYellow());

    // 結果を保存
    document->SaveToFile(L"HighlightSingle.docx", FileFormat::Docx2013);
    document->Close();
}

FindString メソッドの引数は以下の通りです。

  • 第1引数:検索する文字列
  • 第2引数:大文字と小文字を区別するか (true で区別)
  • 第3引数:単語全体に一致させるか (true で単語全体)

すべての出現箇所を検索しハイライトする

文書全体から特定のテキストをすべて検索し、各出現箇所をハイライトするには、FindAllString メソッドを使用します。このメソッドは、マッチしたすべての TextSelection オブジェクトをコレクションで返します。

#include "Spire.Doc.o.h"

using namespace Spire::Doc;
using namespace std;

int main()
{
    intrusive_ptr<Document> document = new Document();
    document->LoadFromFile(L"Input.docx");

    // 特定の文字列を文書全体から検索
    vector<intrusive_ptr<TextSelection>> selections = 
        document->FindAllString(L"Spire.Doc", true, true);

    // 各出現箇所をループで処理
    for (auto selection : selections)
    {
        intrusive_ptr<TextRange> range = selection->GetAsOneRange();
        range->GetCharacterFormat()->SetHighlightColor(Color::GetYellow());
    }

    document->SaveToFile(L"HighlightAll.docx", FileFormat::Docx2013);
    document->Close();
}

このコードでは、FindAllString で取得した全セレクションに対してループを回し、それぞれの背景色を黄色に設定しています。

正規表現にマッチするテキストをハイライトする

特定のパターンに一致するテキストをハイライトしたい場合は、正規表現を用います。FindAllPattern メソッドに Regex オブジェクトを渡すことで、パターンにマッチするすべてのテキストを取得できます。

#include "Spire.Doc.o.h"

using namespace Spire::Doc;
using namespace std;

int main()
{
    intrusive_ptr<Document> doc = new Document();
    doc->LoadFromFile(L"Input.docx");

    // 正規表現パターンを作成(例:数字の並びにマッチ)
    intrusive_ptr<Regex> regex = new Regex(L"\\d+");

    // 正規表現にマッチするすべてのテキストを検索
    vector<intrusive_ptr<TextSelection>> selections = 
        doc->FindAllPattern(regex);

    // マッチした各テキストをハイライト
    for (auto selection : selections)
    {
        intrusive_ptr<TextRange> range = selection->GetAsOneRange();
        range->GetCharacterFormat()->SetHighlightColor(Color::GetSkyBlue());
    }

    doc->SaveToFile(L"HighlightRegex.docx", FileFormat::Docx2013);
    doc->Close();
}

この例では \d+ という正規表現で数字の並びを検索し、該当箇所をスカイブルーでハイライトしています。正規表現のパターンを変更することで、メールアドレスや日付など、様々な形式のテキストを対象にできます。

テキストを検索してフォントの色を変更する

ハイライト(背景色)ではなく、文字色を変更して強調する方法もあります。SetHighlightColor の代わりに SetTextColor を使用します。

#include "Spire.Doc.o.h"

using namespace Spire::Doc;
using namespace std;

int main()
{
    intrusive_ptr<Document> document = new Document();
    document->LoadFromFile(L"Input.docx");

    // テキストを検索
    vector<intrusive_ptr<TextSelection>> selections = 
        document->FindAllString(L"Spire.Doc", false, true);

    for (auto selection : selections)
    {
        intrusive_ptr<TextRange> range = selection->GetAsOneRange();
        // 文字色を赤に設定
        range->GetCharacterFormat()->SetTextColor(Color::GetRed());
        // 太字に設定
        range->GetCharacterFormat()->SetBold(true);
    }

    document->SaveToFile(L"ChangeFontColor.docx", FileFormat::Docx2013);
    document->Close();
}

この方法では、SetTextColor で文字色を変更できるほか、SetBoldSetItalicSetFontSize などのメソッドを使ってフォントスタイルを自由に組み合わせることが可能です。

複数のキーワードをそれぞれ異なる色でハイライトする

文書内に複数のキーワードが存在し、キーワードごとに異なる色でハイライトしたい場合も、同様のアプローチで実装できます。

#include "Spire.Doc.o.h"

using namespace Spire::Doc;
using namespace std;

int main()
{
    intrusive_ptr<Document> doc = new Document();
    doc->LoadFromFile(L"Input.docx");

    // キーワードと対応する色を定義
    vector<wstring> keywords = { L"重要", L"注意", L"確認" };
    vector<Color> colors = { Color::GetYellow(), Color::GetRed(), Color::GetSkyBlue() };

    for (size_t i = 0; i < keywords.size(); i++)
    {
        vector<intrusive_ptr<TextSelection>> selections = 
            doc->FindAllString(keywords[i].c_str(), false, true);

        for (auto selection : selections)
        {
            intrusive_ptr<TextRange> range = selection->GetAsOneRange();
            range->GetCharacterFormat()->SetHighlightColor(colors[i]);
        }
    }

    doc->SaveToFile(L"MultiKeywordHighlight.docx", FileFormat::Docx2013);
    doc->Close();
}

キーワードと色の組み合わせをあらかじめ定義しておくことで、カテゴリ別の色分けハイライトが実現できます。

注意点

  • 本ライブラリは Microsoft Office に依存せず動作しますが、商用利用にはライセンスが必要です。利用前にライセンス条項を確認してください。
  • 文書が大きい場合、FindAllStringFindAllPattern の結果を格納するコレクションのメモリ使用量が増加するため、必要に応じて逐次処理を検討してください。
  • 日本語などマルチバイト文字を扱う際は、ソースファイルの文字エンコーディングが UTF-8 または UTF-16 であることを確認してください。

おわりに

本記事では、Spire.Doc for C++ を用いて Word 文書内のテキストを検索しハイライトする方法として、単一テキストのハイライト、全出現箇所のハイライト、正規表現を用いたパターンマッチハイライト、文字色の変更、複数キーワードの色分けハイライトを紹介しました。いずれも FindStringFindAllStringFindAllPattern の各メソッドと CharacterFormat のプロパティ設定を組み合わせることで実装できます。実際のプロジェクトに組み込む際は、ライセンス形態やメモリ使用量、文字エンコーディングの扱いについて事前に確認することをおすすめします。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?