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

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

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

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

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

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

  1. C1PdfDocumentSourceOpenFileDialogListView、2 つの TextBox、3 つの Button の各コントロールをフォームに追加します。
  2. 次のXAMLコードを追加して、ListViewコントロールに列を追加します。
    XAML
    コードのコピー
    <ListView x:Name="listView1" HorizontalAlignment="Left" Width="585" Margin="10,150,0,10">
        <ListView.HeaderTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="#" Margin="5,5,0,0"></TextBlock>
                    <TextBlock Text="ページ" Margin="15,5,0,0"></TextBlock>
                    <TextBlock Text="発見位置" Margin="40,5,0,0"></TextBlock>
                    <TextBlock Text="近いテキスト内の位置" Margin="40,5,0,0"></TextBlock>
                    <TextBlock Text="近いテキスト" Margin="40,5,0,0"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListView.HeaderTemplate>
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding ID}" Margin="5,0,0,0"></TextBlock>
                    <TextBlock Text="{Binding Page}" Margin="15,0,0,0"></TextBlock>
                    <TextBlock Text="{Binding Bounds}" Margin="30,5,0,0"></TextBlock>
                    <TextBlock Text="{Binding Position}" Margin="30,5,0,0"></TextBlock>
                    <TextBlock Text="{Binding NearText}" Margin="30,5,0,0"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    

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

  1. コードビューに切り替えて、次の名前空間を追加します。
    Imports C1.Xaml.Document
    
    using C1.Xaml.Document;
    
  2. プロジェクトに PDF ファイルを追加します。この例では、製品サンプルにある DefaultDocument.pdf という PDF ファイルを使用します。
  3. 次のコードを追加してC1TextSearchManagerおよびStorageFileクラスのインスタンスを作成します。そして、C1PDFDocumentSourceのインスタンスを初期化し、文字列型の変数loadedFile を宣言します。
    ' 検索で使用されるC1TextSearchManagerのインスタンス。 
    Private tsm As C1TextSearchManager
    
    ' 現在、ロード中のドキュメントの名前。
    Private loadedFile As String = Nothing
    
    Private pds As New C1PdfDocumentSource()
    Private file As StorageFile
    
    // 検索で使用されるC1TextSearchManagerのインスタンス。 
    C1TextSearchManager tsm;
    
    // 現在、ロード中のドキュメントの名前。
    private string loadedFile = null;
    
    C1PdfDocumentSource pds = new C1PdfDocumentSource();
    StorageFile file;
    
  4. InitializeComponent()メソッドの下に次のコードを追加します。
    ' C1TextSearchManagerを作成し、初期化します。
    tsm = New C1TextSearchManager(pds)
    tsm.FoundPositionsChanged += Tsm_FoundPositionsChanged
    
    'UseSystemRenderingをfalseに設定すると、
    '組み込みPDFレンダラを使用したテキスト検索が可能になります。
    pds.UseSystemRendering = False
    
    // C1TextSearchManagerを作成し、初期化します。
    tsm = new C1TextSearchManager(pds);
    tsm.FoundPositionsChanged += Tsm_FoundPositionsChanged;
    
    //UseSystemRenderingをfalseに設定すると、
    //組み込みPDFレンダラーを使用したテキスト検索が可能になります。
    pds.UseSystemRendering = false;
    
  5. 次のコードを追加して、アプリケーションパッケージ内のPDFファイルに直接アクセスします。
    'ms-aapxプロトコルを使用して、アプリケーションパッケージ内のPDFファイルにアクセスします。
    file = Await StorageFile.GetFileFromApplicationUriAsync(New Uri _
           ("ms-appx:///DefaultDocument.pdf"))
    
    ' サンプルファイル
    tbFile.Text = Path.GetFullPath(file.Name)
    
    //ms-aapxプロトコルを使用して、アプリケーションパッケージ内のPDFファイルにアクセスします。
    file = await StorageFile.GetFileFromApplicationUriAsync(new
           Uri("ms-appx:///DefaultDocument.pdf"));
    
    // サンプルファイル
    tbFile.Text = Path.GetFullPath(file.Name);
    
  6. 次のコードを btnFile のクリックイベントに追加して、PDF ファイルを参照して開くためのダイアログボックスを開きます。
    Private Sub btnFile_Click(sender As Object, e As RoutedEventArgs)
       Dim dialog As New FileOpenPicker()
       dialog.ViewMode = PickerViewMode.Thumbnail
       dialog.SuggestedStartLocation = PickerLocationId.Desktop
       dialog.FileTypeFilter.Add(".pdf")
    
       ' ユーザーが検索するPDFファイルを選択できるようにします。
       file = Await dialog.PickSingleFileAsync()
       If file IsNot Nothing Then
           ' アプリケーションは、選択されたファイルへの読み取り/書き込みアクセス権を持つようになりました。
           tbFile.Text = file.Name
       Else
           tbFile.Text = "Operation cancelled."
       End If
    End Sub
    
    private async void btnFile_Click(object sender, RoutedEventArgs e)
    {
        FileOpenPicker dialog = new FileOpenPicker();
        dialog.ViewMode = PickerViewMode.Thumbnail;
        dialog.SuggestedStartLocation = PickerLocationId.Desktop;
        dialog.FileTypeFilter.Add(".pdf");
    
        //  ユーザーが検索するPDFファイルを選択できるようにします。
        file = await dialog.PickSingleFileAsync();
        if (file != null)
        {
            //  アプリケーションは、選択されたファイルへの読み取り/書き込みアクセス権を持つようになりました。
            tbFile.Text = file.Name;
        }
        else
        {
            tbFile.Text = "Operation cancelled.";
        }
    }
    
  7. 次のコードを btnFind のクリックイベントに追加して、テキスト検索を開始します。
    ' テキスト検索を実行します。
    Private Sub btnFind_Click(sender As Object, e As RoutedEventArgs)
       ' 指定されたPDFファイルをc1PdfDocumentSource1にロードして、検索を実行します。
       Try
            Await pds.LoadFromFileAsync(file)
              loadedFile = tbFile.Text
       Catch ex As Exception
            Dim dialog = New MessageDialog(ex.Message)
            Await dialog.ShowAsync()
              Return
       End Try
    
       ' 以前に見つかった位置があれば、それをクリアします。
       listView1.Items.Clear()
    
       ' C1FindTextParamsをユーザが提供する値で初期化します。
       Dim ftp As New C1FindTextParams(tbFind.Text, True, False)
    
       ' 検索を実行します(FindStartAsyncも利用できます)。
       tsm.FindStart(0, True, ftp)
    End Sub
    
         // Perform the text search.
         private async void btnFind_Click(object sender, RoutedEventArgs e)
         {
             // 指定されたPDFファイルをc1PdfDocumentSource1にロードして、検索を実行します。
    Try
             try
             {
                 await pds.LoadFromFileAsync(file);
                 loadedFile = tbFile.Text;
             }
             catch (Exception ex)
             {
                 var dialog = new MessageDialog(ex.Message);
                 await dialog.ShowAsync();
                 return;
             }
    
             // 以前に見つかった位置があれば、それをクリアします。
             listView1.Items.Clear();
    
             // C1FindTextParamsをユーザが提供する値で初期化します。
             C1FindTextParams ftp = new C1FindTextParams(tbFind.Text, true, false);
    
             // 検索を実行します(FindStartAsyncも利用できます)。
             tsm.FindStart(0, true, ftp);
         }
    
  8. 次のコードを追加して、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; }
    }
    
  9. 次のイベントを追加して、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]キーを押してアプリケーションを実行します。
関連トピック