検索

ビューア構成内のネイティブテキスト検索

Doconut Viewer は、フォーマットビューアによって抽出されたテキストまたはテキストベースの PDF リダイレクトを使用した通常の検索を提供します。Search ライセンス機能が必要です。

検索 UI を有効にする

Search は Viewer のモジュールであり、スタンドアロンのツールバーではありません。完全なページには Viewer リソース、Viewer ツールバー、Viewer のマウント、および初期化された objViewer を含める必要があります。その後、Search リボンがマウントされ、同じインスタンスに添付されます。

Search とアノテーションは組み込みのライセンス機能であり、AddPlugin<T>() パッケージではありません。Viewer から検索リソースを要求します。これらのタグは、ライセンスで Search が許可された場合にのみ出力されます。MVC 5 のビューには @inject がないため、コントローラでタグを生成し、ページが必要とするライセンスフラグと共に ViewBag に渡します。

csharp
var viewer = Doconut.DoconutHost.Services.GetRequiredService<Viewer>();
ViewBag.ViewerCss = viewer.ReferenceCss(new CssConfig
{
    IncludeViewerCss = true,
    IncludeSearchCss = true
});
ViewBag.ViewerScripts = viewer.ReferenceScripts(new ScriptConfig
{
    IncludeJQuery        = true,
    IncludeViewerScripts = true,
    IncludeSearchScripts = true,
    IncludeSearchBar     = true
});
ViewBag.IsSearchEnabled = viewer.IsSearchEnabled;

@Html.Raw(ViewBag.ViewerCss) と @Html.Raw(ViewBag.ViewerScripts) を使用してビューに書き込みます。Web Forms では、コードビハインドから同じ値を公開し、<%= %> で書き込みます。

埋め込みリボンは、カスタム UI で利用できる同じ JavaScript メソッドを呼び出します。

マークアップ内で完全な Viewer 構成を可視化したまま、まず docViewer を初期化し、次にライセンス済みリボンを添付します:

html
<nav id="toolbar" aria-label="Document viewer controls">
    <!-- ビューアのコントロール、検索を開くボタンを含む -->
</nav>
<div id="searchBarMount"></div>
<div id="divDocViewer"><div id="div_ctlDoc"></div></div>

<script>
    let searchBar = null;
    let currentToken = '';

    const objViewer = $('#div_ctlDoc').docViewer({
        BasePath: '/',
        ResPath: 'doconut-res/images'
    });

    @if ((bool)ViewBag.IsSearchEnabled)
    {
        <text>
    searchBar = $('#searchBarMount').doconutSearchBar({
        docId: 'ctlDoc',
        getRequestParams: () => ({ token: currentToken }),
        onStatus: (message) => console.log(message),
        onToast: (message, type) => console.log(type, message),
        onLayout: () => requestAnimationFrame(() => objViewer.Refit())
    });
    searchBar.attach(objViewer);
        </text>
    }
</script>

サーバー側の if が重要です。Search 機能がない場合、ReferenceScripts はリボンのスクリプトを除外するため、保護されていない doconutSearchBar(...) 呼び出しは例外をスローし、ビューアページの起動を停止します。Web Forms では、同じガードを <% if (IsSearchEnabled) { %> … <% } %> として記述します。

コンポーネントは Find、Options、Results の各グループを注入し、検索、クリア、マッチ数の表示、前後のマッチナビゲーションを処理します。ホスト側の Viewer ツールバーはそれを切り替えるだけで構いません。

javascript
searchBar.isOpen() ? searchBar.close() : searchBar.open();

その公開 API は意図的にシンプルです:

メソッド目的
attach(objViewer)初期化されたビューアにリボンを接続します。1 回だけ必要です
open() / close()リボンを表示または非表示にします。閉じるとハイライトもクリアされます
reset()現在の検索語、結果数、ハイライトをクリアします
isOpen()リボンが表示されているかどうかを返します
setStatus(message)設定されたコールバックを通じてステータスメッセージを転送します

オプションの onToggle(isOpen) コールバックにより、ホストは Search ボタンと同期させることができ、onLayout によりリボンの高さが変わったときにビューアをリサイズ/再フィットさせることができます。Viewer、Search、Annotation を組み合わせた起動シーケンスについては、クイックスタート を参照してください。

JavaScriptから検索

javascript
objViewer.Search(keyword, false, function (resultCount) {
    console.log('Matches:', resultCount);
});

2番目の引数は単語全体/完全一致を指定します。マッチ数はコールバックで受け取ります。Search 自体はサーバーへ問い合わせを行い、実用的な結果は返さないため、var n = objViewer.Search(keyword, false) は常に undefined を返します。その結果、ページは「何も見つかりません」と表示されますが、ビューアは一致箇所をハイライトします。コールバック後に利用できるものは次のとおりです:

メソッド結果
SearchMatchCount()ドキュメント内の個別マッチの総数。
SearchSummary(false)再描画せずに [pageNumber, matchCount] エントリを取得。
SearchSummary(true)同じサマリーを取得し、ページ/サムネイルのハイライトを描画。
GotoSearchMatch(index)ゼロベースのインデックスでマッチへ移動。

DocImage.axd は search=<term> と exact=true|false のクエリに対して XML を返します。内部レスポンスを自前で解析するのではなく、ウィジェット API を使用してください。

検索機能の確認

初期化レスポンスで次が報告されます:

text
X-Doconut-Can-Search: 1

初期化後、objViewer.CanSearch() は同じ形式/セッションの判定を提供します。サーバーが 0 を送信した場合は false を返し、レスポンスが無い、またはヘッダーが省略された古いサーバーの場合はデフォルトで true になります。

混同してはいけない、3つの独立したゲートがあります:

ゲート質問
CanSearch() / response header解決されたビューアはネイティブインデックス/検索パスを持っていますか?
AllowSearchこの形式の設定でテキスト抽出が有効になっているか?
LicenseCapability.Searchアプリケーションは検索を実行し UI バンドルを受け取る権限がありますか?

形式が技術的に検索可能でも、現在のライセンスが操作を許可していない場合があります。

フォーマットごとの抽出有効化

csharp
var token = await viewer.OpenDocumentAsync(path, new PdfConfig
{
    AllowSearch = true,
    AllowCopy   = true   // オプション: ユーザーが領域をドラッグしてテキストをコピーできるようにします
});

AllowSearch と AllowCopy は PdfConfig、WordConfig、ExcelConfig、PptConfig に存在します。Office のプロパティはそれらのネストされた PdfConfig に委譲します。両方ともデフォルトは false です。

PDF、Word、Excel、PowerPoint、TXT、Visio、メール、EPUB、MHT 用の標準的なネイティブ検索アダプタが存在します。XPS はデフォルトで PDF パスを使用します。HTML と Microsoft Project はテキストベースの PDF リダイレクトの恩恵を受けます:

csharp
// DefaultRender = false → テキストベースの PDF に変換され → 検索可能
var token = await viewer.OpenDocumentAsync(path, new HtmlConfig { DefaultRender = false });

ネイティブレンダラの場合、CanSearch() はビューアの機能を示しますが、特定のドキュメントに利用可能なテキストが含まれていることを保証するものではありません。ページがスキャン画像のみの PDF でも、ネイティブ検索結果はゼロになります。

通常の検索動作

サーバーは検索ソースを以下の順序で試行します:

  1. ネイティブ ISearchableViewer の結果。
  2. 事前構築された .srh 検索インデックス。
  3. 検索ソースが存在しない場合のエラー/空結果。

CanSearch() は検索可能なビューアであっても、特定のドキュメントにテキスト層がなくマッチが返らない場合に true になることがあります。

ライセンスと UI の動作

有効な Temporary/Demo ライセンスは有効期間中に検索機能を提供します。ライセンスが無い場合や旧式の TRIAL ファイルがある場合は検索機能が提供されません。検索が無い場合は:

  • ReferenceCss と ReferenceScripts は検索バンドルを省略します。
  • DocImage.axd は検索リクエストを拒否し、結果を返しません。

カスタム UI の表示は IDoconutLicenseService.IsCapabilityGranted(LicenseCapability.Search) で制御し、形式/セッションごとの判定には CanSearch() を使用してください。

トラブルシューティング

症状確認項目
検索バーが表示されていない検索機能と IncludeSearchCss/IncludeSearchScripts/IncludeSearchBar が有効か
CanSearch() が false形式ビューア、選択された DefaultRender パス、初期化レスポンスヘッダー
スキャンされた PDF で検索結果がゼロになるドキュメントにテキスト層がない;テキストを含むソースまたはテキストを保持する PDF 投影を使用
検索は機能するがハイライトがずれているレンダリングパス、解像度、ドキュメント変換、抽出された単語ボックス

このページは役に立ちましたか?