Поиск

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

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

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

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

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

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
}))

Встроенный ribbon вызывает те же методы JavaScript, доступные пользовательскому интерфейсу.

Сохраните полную композицию Viewer видимой в разметке, сначала инициализируйте docViewer, а затем прикрепите лицензированный Ribbon:

html
<nav id="toolbar" aria-label="Document viewer controls">
    <!-- Viewer controls, including the button that opens Search -->
</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: '/doconut',
        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)Подключить Ribbon к инициализированному viewer; требуется один раз
open() / close()Показать или скрыть Ribbon; закрытие также очищает подсветки
reset()Очистить текущий запрос, количество результатов и подсветки
isOpen()Сообщить, виден ли Ribbon
setStatus(message)Передать сообщение статуса через настроенный обратный вызов

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

Поиск из JavaScript

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

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

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

Маршрут промежуточного слоя использует search=<term> и exact=true|false и возвращает XML. Используйте 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   // optional: lets the user drag a region and copy its text
});

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 → converted to a text-based PDF → searchable
var token = await viewer.OpenDocumentAsync(path, new HtmlConfig { DefaultRender = false });

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

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

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

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

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

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

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

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

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

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

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

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