Поиск

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

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

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

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

Search и аннотация являются встроенными лицензированными функциями, а не пакетами 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, доступные пользовательскому UI.

Сохраните полную композицию 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: '/',
        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 к инициализированному просмотрщику; требуется один раз
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() / заголовок ответаИмеет ли разрешённый просмотрщик нативный индекс/путь поиска?
AllowSearchЗапрашивала ли конфигурация формата извлечение текста, где есть переключатель?
LicenseCapability.SearchРазрешено ли приложению выполнять поиск и получать UI‑пакеты?

Формат может быть технически searchable, тогда как текущая лицензия запрещает операцию.

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

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. Ошибка/пустой результат, когда источник поиска отсутствует.

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

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

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

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

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

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

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

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

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