Document Library for WPF
テキスト検索
PdfDocumentSource for WPF > 機能 > テキスト検索

PDFDocumentSource を使用すると、C1.WPF.Document 名前空間のメンバであるC1TextSearchManager クラスを使用して、検索条件とのマッチングおよびファイルに格納されているすべての単語の検査によるテキスト検索を PDF ファイルに実装できます。このクラスは、検索されるテキストの最初の一致を検索する FindStart、次の一致を検索する FindNext、前の一致を検索する FindPrevious など、さまざまなメソッドを提供します。C1FindTextParams(string text, bool wholeWord, bool matchCase) メソッドを使用して、C1FindTextParams クラスの新しいインスタンスを次のパラメータで初期化できます。

次の図は、PDF ファイルで検索された単語と、検索結果となる一致のリストを示します。

プログラムでテキストを検索するには

このサンプルコードでは、FindStartメソッドを C1TextSearchManager で使用して、検索テキストがある場所を検索します。

手順 1:アプリケーションの設定

  1. C1PdfDocumentSourceOpenFileDialogListView、2 つの TextBox、2 つの Button の各コントロールをフォームに追加します。
  2. 次のXAMLコードを追加して、ListViewコントロールに列を追加します。
    XAML
    コードのコピー
    <ListView x:Name="listView1" Margin="10,106,10,10">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="#" x:Name="chNum" Width="50" DisplayMemberBinding="{Binding ID}" />
                <GridViewColumn Header="ページ" x:Name="chPage" Width="60" DisplayMemberBinding="{Binding Page}"/>
                <GridViewColumn Header="発見位置" x:Name="chBounds" Width="100" DisplayMemberBinding="{Binding Bounds}"/>
                <GridViewColumn Header="近いテキスト内の位置" x:Name="chPosInNearText" Width="60" DisplayMemberBinding="{Binding Position}"/>
                <GridViewColumn Header="近いテキスト" x:Name="chNearText" Width="350" DisplayMemberBinding="{Binding NearText}"/>
            </GridView>
        </ListView.View>
    </ListView>
    

手順 2:PDF ファイルの参照とテキスト検索

  1. コードビューに切り替えて、次の名前空間を追加します。
    Imports C1.WPF.Document
    Imports Microsoft.Win32
    Imports System.IO
    
    using C1.WPF.Document;
    using Microsoft.Win32;
    using System.IO;
    
  2. プロジェクトに PDF ファイルを追加します。この例では、製品サンプルにある DefaultDocument.pdf という PDF ファイルを使用します。
  3. 次のコードを追加して、C1TextSearchManager クラスのインスタンスを作成し、C1PDFDocumentSourceのインスタンスを初期化します。そして、文字列型の変数 loadedFileを宣言します。
    ' 検索で使用されるC1TextSearchManagerのインスタンス  
    Private tsm As C1TextSearchManager
    
    ' 現在、ロード中のドキュメントの名前
    Private loadedFile As String = Nothing
    
    Private pds As New C1PdfDocumentSource()
    
    // 検索で使用されるC1TextSearchManagerのインスタンス
    C1TextSearchManager tsm;
    
    //現在、ロード中のドキュメントの名前
    private string loadedFile = null;
            
    C1PdfDocumentSource pds = new C1PdfDocumentSource();
    
  4. 次のコードを InitializeComponent() メソッドの下に追加します。
    ' サンプルファイル
    tbFile.Text = System.IO.Path.GetFullPath("..\..\DefaultDocument.pdf")
    
    ' C1TextSearchManagerを作成し、初期化します
    tsm = New C1TextSearchManager(pds)
    tsm.FoundPositionsChanged += tsm_FoundPositionsChanged
    
    // サンプルファイル。
    tbFile.Text = System.IO.Path.GetFullPath(@"..\..\DefaultDocument.pdf");
    
    //C1TextSearchManagerを作成し、初期化します
    tsm = new C1TextSearchManager(pds);
    tsm.FoundPositionsChanged += tsm_FoundPositionsChanged;
    
  5. 次のコードを btnFile のクリックイベントに追加して、PDF ファイルを参照して開くためのダイアログボックスを開きます。
    ' ユーザーが検索するPDFファイルを選択できるようにします。
    Dim dialog As New OpenFileDialog()
    If dialog.ShowDialog(Me) = True Then
            tbFile.Text = dialog.FileName
    End If
    
    // ユーザーが検索するPDFファイルを選択できるようにします。\
    OpenFileDialog dialog = new OpenFileDialog();
    if (dialog.ShowDialog(this) == true)
    {
        tbFile.Text = dialog.FileName;
    }
    
  6. 次のコードを btnFind のクリックイベントに追加して、テキスト検索を開始します。
    ' 指定されたPDFファイルをc1PdfDocumentSource1にロードして、検索を実行します。
    Try
       pds.LoadFromFile(tbFile.Text)
       loadedFile = tbFile.Text
    Catch ex As Exception
       MessageBox.Show(Me, ex.Message, "Error", MessageBoxButton.OK, _
                       MessageBoxImage.[Error])
         Return
    End Try
    
    ' 以前に見つかった位置があれば、それをクリアします。
    listView1.Items.Clear()
    
    ' C1FindTextParamsをユーザが提供する値で初期化します。
    Dim ftp As New C1FindTextParams(tbFind.Text, True, False)
    
    ' 検索を実行します(FindStartAsyncも利用できます)。
    tsm.FindStart(0, True, ftp)
    
    // 指定されたPDFファイルをc1PdfDocumentSource1にロードして、検索を実行します。
    try
    {
         pds.LoadFromFile(tbFile.Text);
         loadedFile = tbFile.Text;
    }
    catch (Exception ex)
    {
         MessageBox.Show(this, ex.Message, "エラー", MessageBoxButton.OK,
                         MessageBoxImage.Error);
         return;
    }
    
    // 以前に見つかった位置があれば、それをクリアします。
    listView1.Items.Clear();
    
    // C1FindTextParamsをユーザが提供する値で初期化します。
    C1FindTextParams ftp = new C1FindTextParams(tbFind.Text, true, false);
    
    // 検索を実行します(FindStartAsyncも利用できます)。
    tsm.FindStart(0, true, ftp);
    
  7. 次のコードを追加して、SearchItemというクラスを作成します。
    Public Class SearchItem
            Public Property ID() As Integer
                    Get
                            Return m_ID
                    End Get
                    Set
                            m_ID = Value
                    End Set
            End Property
            Private m_ID As Integer
            Public Property Page() As String
                    Get
                            Return m_Page
                    End Get
                    Set
                            m_Page = Value
                    End Set
            End Property
            Private m_Page As String
            Public Property Bounds() As String
                    Get
                            Return m_Bounds
                    End Get
                    Set
                            m_Bounds = Value
                    End Set
            End Property
            Private m_Bounds As String
            Public Property Position() As String
                    Get
                            Return m_Position
                    End Get
                    Set
                            m_Position = Value
                    End Set
            End Property
            Private m_Position As String
            Public Property NearText() As String
                    Get
                            Return m_NearText
                    End Get
                    Set
                            m_NearText = Value
                    End Set
            End Property
            Private m_NearText As String
    End Class
    
    public class SearchItem
    {
        public int ID { get; set; }
        public string Page { get; set; }
        public string Bounds { get; set; }
        public string Position { get; set; }
        public string NearText { get; set; }
    }
    
  8. 次のイベントを追加して、UI の発見位置のリストを更新します。
    ' C1TextSearchManagerのFoundPositionsコレクションが変更されたとき(つまり、
    ' 検索テキストの新しいインスタンスが見つかったとき)に呼び出されます。
    ' これを使用して、UI内で見つかった位置のリストを更新します。
    Private Sub tsm_FoundPositionsChanged(sender As Object, e As EventArgs)
       Dim n As Integer = tsm.FoundPositions.Count
       For i As Integer = listView1.Items.Count To n - 1
          Dim fp As C1FoundPosition = tsm.FoundPositions(i)
          Dim bounds = fp.GetBounds()
    
          listView1.Items.Add(New SearchItem() With { _
             .ID = i + 1, _
             .Page = fp.GetPage().PageNo.ToString(), _
             .Bounds = String.Format("{0}, {1}, {2}, {3}", _
                       CInt(Math.Round(bounds.Left)), _
                       CInt(Math.Round(bounds.Top)), _
                       CInt(Math.Round(bounds.Width)), _
                       CInt(Math.Round(bounds.Height))), _
             .Position = fp.PositionInNearText.ToString(), _
             .NearText = fp.NearText _
          })
       Next
    End Sub
    
    // C1TextSearchManagerのFoundPositionsコレクションが変更されたとき(つまり、
    // 検索テキストの新しいインスタンスが見つかったとき)に呼び出されます。
    // これを使用して、UI内で見つかった位置のリストを更新します。
    private void tsm_FoundPositionsChanged(object sender, EventArgs e)
    {
        int n = tsm.FoundPositions.Count;
        for (int i = listView1.Items.Count; i < n; i++)
        {
            C1FoundPosition fp = tsm.FoundPositions[i];
            var bounds = fp.GetBounds();
    
            listView1.Items.Add(new SearchItem
            {
                ID = i + 1,
                Page = fp.GetPage().PageNo.ToString(),
                Bounds = string.Format("{0}, {1}, {2}, {3}",
                         (int)Math.Round(bounds.Left),
                         (int)Math.Round(bounds.Top),
                         (int)Math.Round(bounds.Width),
                         (int)Math.Round(bounds.Height)),
                Position = fp.PositionInNearText.ToString(),
                NearText = fp.NearText
            });
        }     
    }
    

手順 3:プロジェクトのビルドおよび実行

  1. [Ctrl]+[Shift]+[B]キーを押してプロジェクトをビルドします。
  2. [F5]キーを押してアプリケーションを実行します。
関連トピック