Поиск

Нативный текстовый поиск в композиции Viewer

Doconut Viewer предоставляет обычный поиск, используя текст, извлечённый просмотрщиком формата, или перенаправление PDF на основе текста. Для работы требуется возможность лицензии Search.

Включить пользовательский интерфейс поиска

Поиск — это модуль Viewer, а не отдельная панель инструментов. Полная страница должна включать ресурсы Viewer, панель инструментов Viewer, монтирование Viewer и инициализированный objViewer; затем лента поиска монтируется и присоединяется к тому же экземпляру.

Поиск и аннотация являются встроенными лицензированными функциями, а не пакетами AddPlugin<T>(). Запросите ресурсы поиска у внедрённого Viewer; их теги выдаются только когда лицензия предоставляет поиск.

html
@Html.Raw(Viewer.ReferenceCss(new CssConfig
{
    IncludeViewerCss = true,
    IncludeSearchCss = true
}))

@Html.Raw(Viewer.ReferenceScripts(new ScriptConfig
{
    IncludeJQuery = true,
    IncludeViewerScripts = true,
    IncludeSearchScripts = true,
    IncludeSearchBar = true
}))

Встроенная лента вызывает те же методы 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 (Viewer.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>

Компонент внедряет группы Find, Options и Results и обрабатывает поиск, очистку, подсчёт совпадений и навигацию к предыдущему/следующему совпадению. Панель инструментов Viewer, принадлежащая хосту, просто должна переключать её:

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

Её публичный API намеренно небольшой:

МетодНазначение
attach(objViewer)Подключить ленту к инициализированному viewer; требуется один раз
open() / close()Показать или скрыть ленту; закрытие также очищает подсветки
reset()Очистить текущий запрос, количество результатов и подсветки
isOpen()Сообщить, видна ли лента
setStatus(message)Переслать статусное сообщение через настроенный callback

Опциональный callback onToggle(isOpen) позволяет хосту синхронизировать кнопку поиска, а onLayout позволяет изменять размер/подгонять viewer, когда высота ленты меняется. Для последовательности запуска объединённого Viewer, Search и Annotation см. Быстрый старт.

Поиск из JavaScript

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

Второй аргумент отвечает за поиск целых слов/точное совпадение. После callback:

МетодРезультат
SearchMatchCount()Общее количество отдельных совпадений в документе.
SearchSummary(false)[pageNumber, matchCount] записи без перерисовки.
SearchSummary(true)Тот же сводный результат и отрисовка подсветки страниц/миниатюр.
GotoSearchMatch(index)Переходит к совпадению по нулевому индексу.

Маршрут промежуточного слоя использует search=<term> и exact=true|false и возвращает XML. Используйте widget API вместо самостоятельного разбора внутреннего ответа.

Проверка возможности поиска

Ответ инициализации сообщает:

text
X-Doconut-Can-Search: 1

После инициализации objViewer.CanSearch() раскрывает тот же вердикт формата/сессии. Он возвращает false, когда сервер отправляет 0; до ответа или при более старом сервере, который опускает заголовок, значение по умолчанию — true.

Три независимых условия не должны путаться:

УсловиеВопрос
CanSearch() / заголовок ответаИмеет ли разрешённый viewer нативный индекс/путь поиска?
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, email, EPUB и MHT. XPS по умолчанию использует свой путь PDF. HTML и Microsoft Project выигрывают от перенаправления PDF на основе текста:

csharp
// DefaultRender = false → преобразовано в PDF на основе текста → доступно для поиска
var token = await viewer.OpenDocumentAsync(path, new HtmlConfig { DefaultRender = false });

Для нативных рендереров CanSearch() описывает возможности viewer; это не гарантирует, что конкретный документ содержит пригодный текст. PDF, страницы которого являются только отсканированными изображениями, всё равно может давать ноль нативных результатов.

Обычное поведение поиска

Сервер пытается использовать источники поиска в следующем порядке:

  1. Результаты из нативного viewer формата.
  2. Предварительно построенный индекс поиска .srh.
  3. Ошибка/пустой результат, когда источник поиска отсутствует.

Индекс .srh — это артефакт поиска, публикуемый вместе с изображениями страниц, когда документы обслуживаются из общего хранилища, поэтому узел, который никогда не открывал документ, всё равно может отвечать на запросы поиска — см. Распределённые развертывания.

CanSearch() может быть истинным для поискового viewer, даже если конкретный отсканированный документ не имеет текстового слоя и, следовательно, не возвращает совпадений.

Лицензирование и поведение UI

Активная временная/демо лицензия предоставляет поиск в течение своего активного периода. Отсутствующая лицензия и устаревший файл TRIAL не предоставляют возможности поиска. Без поиска:

  • ReferenceCss и ReferenceScripts исключают поисковые пакеты.
  • Промежуточный слой отклоняет поиск вместо возврата лицензированных результатов.

Управляйте видимостью пользовательского UI через IDoconutLicenseService.IsCapabilityGranted(LicenseCapability.Search) и используйте CanSearch() для отдельного вердикта формата/сессии.

Устранение неполадок

СимптомПроверка
Панель поиска отсутствуетВозможность поиска и IncludeSearchCss/IncludeSearchScripts/IncludeSearchBar
CanSearch() ложноПросмотрщик формата, выбранный путь DefaultRender и заголовок ответа инициализации
Поиск возвращает ноль для отсканированного PDFДокумент не имеет текстового слоя; используйте источник с текстом или проекцию PDF, сохраняющую текст
Поиск работает, но подсветка смещенаПуть рендеринга, разрешение, трансформации документа и извлечённые коробки слов

Была ли эта страница полезной?