Найдите, исправьте, проверьте: Полное руководство по Aspose.Cells Cloud Search, Replace & Broken-Link API (.NET / Python / Java / cURL)

“Какая из наших 400 бюджетных рабочих книг всё ещё содержит Old Vendor Ltd?” “Замените каждый заполнитель {{COMPANY}} в этом шаблоне.” “Есть ли в каких‑либо наших отчётах ссылки на тот домен, который мы закрыли в прошлом году?” — три совершенно разных вопроса, один общий ответ: REST‑запрос, который читает и переписывает электронные таблицы в облаке, без установленного Excel где‑либо.

Проблемы с контентом электронных таблиц появляются почти в каждом коде, насыщенном данными:

  • Content audit — поиск каждой ячейки, фигуры или гиперссылки, в которой упоминается устаревшее название продукта, старый адрес офиса или неактуальная юридическая единица;
  • Template rendering — заполнение токенов {{PLACEHOLDER}} по листам перед отправкой рабочей книги клиенту;
  • Link rot — проверка того, что URL‑адреса, встроенные в рабочую книгу, всё ещё работают, перед тем как задача по соответствию или архивированию одобрит её;
  • Bulk correction — исправление опечатки или ошибочного значения столбца в десятках листов или в пределах одной области одного листа.

Традиционные варианты — библиотека скриптов, работающая на вашем компьютере, макрос Excel или COM‑компонент на сервере Windows — всё это означает, что именно вы размещаете и масштабируете логику работы с электронными таблицами. Aspose.Cells Cloud превращает это в простой REST: отправьте файл (или просто имя файла), получите совпадения — или исправленный файл — обратно.

В этом посте рассматриваются API, предоставляемые основным SearchController в микросервисе Aspose.Cells Cloud (исходный код: src/Aspose.Cells.Cloud.MicroService/Controllers/SearchController.cs), с работающими примерами на cURL и C# (.NET), а также примечаниями для пользователей Python и Java.

1. Что может делать SearchController?

SearchController охватывает три семейства возможностей, каждое доступно в нескольких областях:

Семейство Что делает Изменяет книгу?
Поиск Возвращает текстовые элементы, соответствующие запросу — с их листом и позицией ячейки/фигуры/гиперссылки Нет
Заменить Заменяет найденный текст, затем либо передаёт исправленный файл обратно в поток, либо сохраняет его в облачное хранилище Да
Неисправные ссылки Проверяет каждую гиперссылку http(s) в книге и возвращает те, которые не удалось разрешить Нет

И каждая семья доступна в четырех областях, именно там список конечных точек становится длинным:

Область Поиск Замена Неисправные ссылки
Локальный файл → онлайн‑обработка (загрузка в теле запроса) PUT /v4.0/cells/search/content PUT /v4.0/cells/replace/content PUT /v4.0/cells/search/broken-links
Вся книга в облачном хранилище PUT /v4.0/cells/{name}/search/content PUT /v4.0/cells/{name}/replace/content PUT /v4.0/cells/{name}/search/broken-links
Один лист в облачном хранилище PUT /v4.0/cells/{name}/worksheets/{worksheet}/search/content PUT /v4.0/cells/{name}/worksheets/{worksheet}/replace/content PUT /v4.0/cells/{name}/worksheets/{worksheet}/search/broken-links
Один диапазон в облачном хранилище PUT /v4.0/cells/{name}/worksheets/{worksheet}/ranges/{cellArea}/search/content PUT /v4.0/cells/{name}/worksheets/{worksheet}/ranges/{cellArea}/replace/content PUT /v4.0/cells/{name}/worksheets/{worksheet}/ranges/{cellArea}/search/broken-links

Плюс два дополнительных конечных пункта, которые выводят каждый текстовый элемент в рабочей книге — см. §4:

Цель Конечная точка
Все текстовые элементы в облачном файле PUT /v4.0/cells/{name}/search/content/all-textitems
Все текстовые элементы в локальной загрузке PUT /v4.0/cells/search/content/all-textitems

Примечание к реализации: маршруты имеют префикс v{version:apiVersion}/cells и этот контроллер имеет [ApiVersion("4.0")], поэтому живые вызовы выглядят как https://api.aspose.cloud/v4.0/cells/.... Всё в этом контроллере — это PUT — даже поисковые запросы только для чтения — потому что поиск моделируется как операция, отправленная к ресурсу, а не кэшируемый GET.

Два режима работы и почему они важны

Контроллер декорирует каждое действие, а декоратор точно указывает, откуда берётся файл:

  • [OnlineOperation] — stateless. Вы загружаете рабочую книгу в теле запроса (multipart), сервер обрабатывает её в памяти, и ничего не сохраняется в облачном хранилище. Идеально подходит для «просто скажи, что находится в этом файле» и однократного шаблонирования.
  • [CloudFileOperation] — storage-backed. Сервер получает {name} из облачного хранилища (при необходимости из folder=), выполняет работу и — для операций замены — записывает результат сразу обратно. Ничего не передаётся на ваш компьютер.

Это единственное различие, плюс сегменты маршрута {worksheet} / {cellArea}, составляет всю ментальную модель. Остальная часть этой записи — лишь детали.


2. Модели ответов, которые вы действительно будете разбирать

Обе семейства поиска возвращают небольшую, плоскую, легко привязываемую форму. Поиск возвращает SearchResponse:

{
  "Code": 200,
  "Status": "OK",
  "TextItems": [
    {
      "Filename": "Book1.xlsx",
      "Worksheet": "Q3 Forecast",
      "Position": "Cell:B7",
      "Content": "Old Vendor Ltd"
    },
    {
      "Filename": "Book1.xlsx",
      "Worksheet": "Q3 Forecast",
      "Position": "Shape:TextBox 3",
      "Content": "Prepared by Old Vendor Ltd"
    }
  ]
}

Поиск битых ссылок возвращает BrokenLinksResponse:

{
  "Code": 200,
  "Status": "OK",
  "BrokenLinks": [
    {
      "Filename": "Book1.xlsx",
      "Worksheet": "Links",
      "Position": "Hyperlink:Sheet1!B4",
      "LinkAddress": "https://retired-domain.example.com/report"
    }
  ]
}

Две вещи стоит отметить сразу:

  1. Position — это помеченное местоположение, а не просто адрес ячейки. Оно имеет префикс Cell:, Hyperlink: или Shape:, что позволяет единому плоскому списку определить, какой тип объекта совпал. Этот тег — разница между «исправить ячейку B7» и «исправить текстовое поле, расположенное над B7».

  2. Обе модели самодокументированы для отчетности — Filename и Worksheet возвращаются для каждого элемента, поэтому сканирование множества книг может быть объединено в одну таблицу аудита без последующей обработки.

3. Два вещи, которые вам нужны перед тем как начать

  1. Зарегистрируйте бесплатный аккаунт на Aspose Cloud Dashboard и создайте приложение, чтобы получить Client ID и Client Secret (SDK автоматически обменивают их на JWT — нет необходимости самостоятельно формировать заголовки авторизации).
  2. Установите SDK для выбранного вами языка:
<!-- .NET -->
<PackageReference Include="Aspose.Cells-Cloud" Version="25.x" />
# Python
pip install asposecellscloud
<!-- Java (Maven) — note: NOT on Maven Central, so the Aspose repo below is required -->
<repositories>
    <repository>
        <id>AsposeJavaAPI</id>
        <name>Aspose Java API</name>
        <url>https://repository.aspose.cloud/repo/</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.aspose</groupId>
    <artifactId>aspose-cells-cloud</artifactId>
    <version>26.8</version>
</dependency>

Не нужен SDK? Всё — обычный REST, поэтому cURL работает так же хорошо (см. ниже). Семейство запросов поиска/замены/битых ссылок также доступно через типизированные модели запросов SDK — SearchSpreadsheetContentRequest, ReplaceContentInRemoteRangeRequest и их аналоги — что и используется в сниппетах C# ниже.


4. Сценарий A: Поиск локального файла онлайн (ничего не сохраняется)

Это PUT /v4.0/cells/search/content — загрузите книгу, получите совпадения. Нет облачного хранилища, нет очистки, никаких копий не остаётся.

① cURL

# 1) First, get a token
curl -X POST "https://api.aspose.cloud/connect/token" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"

# 2) Find "Old Vendor Ltd" anywhere in a local workbook
curl -X PUT "https://api.aspose.cloud/v4.0/cells/search/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText=Old Vendor Ltd" \
  --data-urlencode "ignoringCase=true" \
  -F "file=@Book1.xlsx"

Сузьте его до одного листа или до одной области одного листа, используя два дополнительных параметра запроса:

# Only "Q3 Forecast", only the range A1:F40
curl -X PUT "https://api.aspose.cloud/v4.0/cells/search/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText=Old Vendor Ltd" \
  --data-urlencode "worksheet=Q3 Forecast" \
  --data-urlencode "cellArea=A1:F40" \
  -F "file=@Book1.xlsx"

② C# / .NET

using Aspose.Cells.Cloud.SDK.Api;
using Aspose.Cells.Cloud.SDK.Request;

var cellsApi = new CellsApi("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET");

// Local file, whole workbook
var request = new SearchSpreadsheetContentRequest(
    spreadsheet:  "C:/audit/Book1.xlsx",   // local file path
    searchText:   "Old Vendor Ltd",
    ignoringCase: true);

SearchResponse response = cellsApi.SearchSpreadsheetContent(request);

foreach (var item in response.TextItems)
{
    Console.WriteLine($"{item.Worksheet} | {item.Position} | {item.Content}");
}
// Same call, scoped to one sheet and one range
var scoped = new SearchSpreadsheetContentRequest(
    spreadsheet:  "C:/audit/Book1.xlsx",
    searchText:   "Old Vendor Ltd",
    ignoringCase: true,
    sheetname:    "Q3 Forecast",
    cellarea:     "A1:F40");

Модели запросов также предоставляют password (открыть защищённую книгу) и regoin (настройка региона/локали) — те же необязательные параметры, которые вы увидите в вариантах cloud-storage как storageName. Обратите внимание, что .NET SDK сохраняет написание regoin; Python SDK называет эти две настройки password и region.

③ Python / Java

Python SDK оборачивает тот же набор конечных точек, при этом поля модели запроса отображаются на C# поля один‑к‑одному, но в snake_case:

from asposecellscloud.apis.cells_api import CellsApi
from asposecellscloud.requests import (
    SearchSpreadsheetContentRequest,
    SearchContentInRemoteRangeRequest,
)

instance = CellsApi("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")

# Local upload — returned items carry Worksheet / Position / Content
local = instance.search_spreadsheet_content(
    SearchSpreadsheetContentRequest(
        "Book1.xlsx", "Old Vendor Ltd",
        ignoring_case=True, worksheet="Q3 Forecast", cell_area="A1:F40"))

# Range-scoped search of a file already in cloud storage
remote = instance.search_content_in_remote_range(
    SearchContentInRemoteRangeRequest(
        "Book1.xlsx", "Q3 Forecast", "A1:F40", "Old Vendor Ltd",
        ignoring_case=True, folder="Reports"))

for item in remote.text_items:
    print(item.worksheet, item.position, item.content)

Java SDK следует той же схеме, где объекты Request создаются с помощью сеттеров:

import com.aspose.cloud.cells.api.CellsApi;
import com.aspose.cloud.cells.model.SearchResponse;
import com.aspose.cloud.cells.request.SearchContentInRemoteRangeRequest;

public class SearchDemo {
    public static void main(String[] args) throws Exception {
        CellsApi api = new CellsApi("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET");

SearchContentInRemoteRangeRequest req = new SearchContentInRemoteRangeRequest();
        req.setName("Book1.xlsx");
        req.setWorksheet("Q3 Forecast");
        req.setCellArea("A1:F40");
        req.setSearchText("Old Vendor Ltd");
        req.setIgnoringCase(true);
        req.setFolder("Reports");

SearchResponse response = api.searchContentInRemoteRange(req);
        response.getTextItems().forEach(i ->
            System.out.println(i.getWorksheet() + " | " + i.getPosition() + " | " + i.getContent()));
    }
}

Если вы используете чистый REST, приведённый выше cURL представляет собой полный контракт — поле multipart просто должно содержать имя файла, поскольку сервис выводит имя рабочей книги (а соответственно и её формат) из него.

5. Сценарий B: Поиск файла, который уже находится в облачном хранилище

Если рабочая книга уже находится в Aspose Cloud Storage, полностью пропустите загрузку — сервис читает её там, где она находится:

# Whole workbook
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/search/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText=Old Vendor Ltd" \
  --data-urlencode "ignoringCase=true" \
  --data-urlencode "folder=Reports"

# Just one worksheet
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/worksheets/Q3%20Forecast/search/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText=Old Vendor Ltd"

# Just one range of one worksheet
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/worksheets/Q3%20Forecast/ranges/A1:F40/search/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText=Old Vendor Ltd"
// Whole workbook in storage
var response = cellsApi.SearchContentInRemoteSpreadsheet(
    new SearchContentInRemoteSpreadsheetRequest(
        name:         "Book1.xlsx",
        searchText:   "Old Vendor Ltd",
        ignoringCase: true,
        folder:       "Reports"));

// One worksheet
var sheetHits = cellsApi.SearchContentInRemoteWorksheet(
    new SearchContentInRemoteWorksheetRequest(
        name:       "Book1.xlsx",
        sheetname:  "Q3 Forecast",
        searchText: "Old Vendor Ltd",
        folder:     "Reports"));

// One range
var rangeHits = cellsApi.SearchContentInRemoteRange(
    new SearchContentInRemoteRangeRequest(
        name:        "Book1.xlsx",
        sheetname:   "Q3 Forecast",
        cellArea:    "A1:F40",
        searchText:  "Old Vendor Ltd",
        ignoringCase: true,
        folder:      "Reports"));

Почему три конечные точки вместо одной? Потому что маршрут несёт область. Конечная точка whole-workbook принимает имя и запрос; конечная точка worksheet принимает сегмент листа; конечная точка range принимает лист и сегмент диапазона. Это чистая, кэшируемая форма REST — и это означает, что параметры «уточнить поиск» (worksheet, cellArea) существуют только на конечной точке local-file, что стоит помнить при переносе вызова из одной области в другую.

6. Сценарий C: Получить каждый текстовый элемент в рабочей книге

Иногда у вас нет поискового запроса — вам нужен полный список. Конечные точки all-textitems возвращают каждый текстовый элемент в рабочей книге, так что вы можете сравнить две версии, создать глоссарий переводов или передать данные индексатору:

# Cloud file — every text item
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/search/content/all-textitems" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "folder=Reports"

# Local upload — every text item
curl -X PUT "https://api.aspose.cloud/v4.0/cells/search/content/all-textitems" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@Book1.xlsx"

Ответ имеет тот же конверт SearchResponse, при этом Content заполнен для каждой строки ячейки, подписи гиперссылки и текста фигуры в файле. Это примитив «grep the whole workbook».

7. Сценарий D: Замена — и два совершенно разных результата

Replace — это место, где API делится на две части, и это разделение преднамеренно:

Локальная загрузка → скачать исправленный файл Файл в облаке → сохранён обратно в хранилище
Конечная точка PUT /v4.0/cells/replace/content PUT /v4.0/cells/{name}/replace/content
Возвращаемое значение Поток файла (тот же формат, что вы загрузили) CellsCloudResponse { "Code": 200, "Status": "OK" }
Хранилище затронуто Нет Исходный файл перезаписан

① Замена в локальной рабочей книге, потоковая передача результата обратно

curl -X PUT "https://api.aspose.cloud/v4.0/cells/replace/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText={{COMPANY}}" \
  --data-urlencode "replaceText=Northwind Traders" \
  -F "file=@template.xlsx" \
  -o template-rendered.xlsx
using Aspose.Cells.Cloud.SDK.Request;

var request = new ReplaceSpreadsheetContentRequest(
    spreadsheet: "C:/templates/template.xlsx",
    searchText:  "{{COMPANY}}",
    replaceText: "Northwind Traders");

// Option A: get the corrected workbook as a Stream
using Stream corrected = cellsApi.ReplaceSpreadsheetContent(request);
using var outFile = File.Create("C:/templates/template-rendered.xlsx");
corrected.CopyTo(outFile);

// Option B: let the SDK write it for you (.NET overload with an output path)
// cellsApi.ReplaceSpreadsheetContent(request, "C:/templates/template-rendered.xlsx");

Здесь также доступны два параметра области — sheetname и cellarea — так что вы можете отрисовывать заполнители в одном листе, не затрагивая остальную часть шаблона.

② Замена в облачной рабочей книге, сохранение на месте

# Whole workbook, saved back to storage
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/replace/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText=Old Vendor Ltd" \
  --data-urlencode "replaceText=Northwind Traders" \
  --data-urlencode "folder=Reports"

# One worksheet
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/worksheets/Q3%20Forecast/replace/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText=Old Vendor Ltd" \
  --data-urlencode "replaceText=Northwind Traders" \
  --data-urlencode "folder=Reports"

# One range
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/worksheets/Q3%20Forecast/ranges/A1:F40/replace/content" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "searchText=Old Vendor Ltd" \
  --data-urlencode "replaceText=Northwind Traders" \
  --data-urlencode "folder=Reports"
// Whole workbook — result saved back into cloud storage
cellsApi.ReplaceContentInRemoteSpreadsheet(
    new ReplaceContentInRemoteSpreadsheetRequest(
        name:        "Book1.xlsx",
        searchText:  "Old Vendor Ltd",
        replaceText: "Northwind Traders",
        folder:      "Reports"));

// Range-scoped
cellsApi.ReplaceContentInRemoteRange(
    new ReplaceContentInRemoteRangeRequest(
        name:        "Book1.xlsx",
        searchText:  "Old Vendor Ltd",
        replaceText: "Northwind Traders",
        worksheet:   "Q3 Forecast",
        cellarea:    "A1:F40",
        folder:      "Reports"));

Замена на месте по умолчанию разрушительна. Варианты в облаке перезаписывают {name} — резервная копия не создаётся. Для процессов с интенсивным аудитом храните версионированную копию (например, сначала загрузите Book1-2026-09-11.xlsx, затем замените) или используйте вариант локальной загрузки и сохраняйте полученный поток самостоятельно.


8. Сценарий E: Найдите битые ссылки, пока их не нашёл кто‑то другой

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

# Local workbook, whole file
curl -X PUT "https://api.aspose.cloud/v4.0/cells/search/broken-links" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@Book1.xlsx"

# Cloud workbook, whole file
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/search/broken-links" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "folder=Reports"

# Cloud workbook, one worksheet
curl -X PUT "https://api.aspose.cloud/v4.0/cells/Book1.xlsx/worksheets/Links/search/broken-links" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "folder=Reports"
var broken = cellsApi.SearchSpreadsheetBrokenLinks(
    new SearchSpreadsheetBrokenLinksRequest(
        spreadsheet: "C:/audit/Book1.xlsx"));

foreach (var link in broken.BrokenLinks)
{
    Console.WriteLine($"{link.Worksheet} {link.Position} -> {link.LinkAddress}");
}

Результат — это список, с которым можно работать напрямую: каждая запись указывает лист, позицию и проблемный LinkAddress.


9. Что именно сканируется? (детали реализации, меняющие ваши ожидания)

Это часть, которая отличает работающую интеграцию от неожиданной. Читая WorkbookExtension.cs, поиск проходит три разных типа элементов в каждом листе:

Тип элемента Источник Что сопоставляется Position тег
Строки ячеек worksheet.Cells Строковое значение ячейки Cell:A1
Гиперссылки worksheet.Hyperlinks И адрес ссылки и её текст отображения Hyperlink:Sheet1!B4
Фигуры worksheet.Shapes shape.Text — текстовые поля, выноски, метки Shape:TextBox 3

И вот поведения, о которых стоит знать до того, как вы проектируете их:

Ищутся только ячейки со строковым значением. Сканирование фильтрует по CellValueType.IsString. Ячейка, содержащая число, дату или логическое значение, пропускается — поэтому поиск 2025 не совпадет с ячейкой, отформатированной как дата, у которой серийное значение случайно равно 2025. Ячейки, формулы которых оцениваются как текст, совпадают, потому что их тип значения — строка.

Чувствительность к регистру — единственная опция сопоставления. ignoringCase переключается между сравнением InvariantCultureIgnoreCase и InvariantCulture — ничего больше. Нет режима полного слова, regex или «соответствия всему значению ячейки», несмотря на то, что могут подразумевать сгенерированные API‑документы. Если вам нужны такие семантики, получите инвентарь all-textitems и отфильтруйте его самостоятельно.

Replace — простая, чувствительная к регистру, буквальная замена. Флаг ignoringCase у Search не имеет эквивалента в Replace — путь замены не имеет параметра нечувствительности к регистру. И два пути кода различаются внутри: замена всего листа делегирует вызов Worksheet.Replace(...) движку, тогда как замена в диапазоне проходит по диапазону и переписывает каждую строковую ячейку с помощью cell.StringValue.Replace(...). Практический вывод: замена в диапазоне затрагивает только строковые ячейки, и она буквальная, а не основанная на шаблонах.

Сопоставления гиперссылок возвращают адрес, а не подпись. Когда поиск совпадает с текстом отображения гиперссылки, возвращаемый Content всё равно hyperlink.Address. Если вы формируете отчет «found it here», ожидайте URL — подпись не возвращается.

Проверка битых ссылок учитывает только http:// и https://. mailto: ссылки, локальные пути к файлам и внутренние якоря #Sheet1!A1 полностью пропускаются — они никогда не тестируются, поэтому не появятся в результатах. Она также сканирует гиперссылки, прикреплённые к формам и ячейкам, именно там мертвые ссылки любят прятаться. Обратите внимание, что Position битой ссылки формируется из необработанного hyperlink.Area (не из более удобного Area.ToRangName(), используемого поисковыми конечными точками), поэтому не следует полагать, что обе семьи отображают позиции одинаково — разберите пару Worksheet + LinkAddress, если нужен стабильный ключ.

“Broken” означает “недоступен”, а не “неправильный код состояния”. Проверка отправляет HTTP HEAD запрос для каждой ссылки и рассматривает любой ответ — включая 404 или 500 — как доступный; ссылка помечается как сломанная только когда запрос выбрасывает исключение (ошибка DNS, отказ в соединении, ошибка TLS, тайм‑аут). Таким образом, рассматривайте вывод как “ссылки, с которыми не удалось установить связь”. Если же вам действительно нужны “ссылки, которые не возвращают 2xx”, вам следует самостоятельно перепроверить полученные значения LinkAddress.

cellArea принимается, но не применяется к конечным точкам broken-link. Реализация BrokenLinks фильтрует только по имени листа; аргумент cell-area передаётся, но никогда не используется. На практике это означает, что .../ranges/A1:F40/search/broken-links в настоящее время ведёт себя так же, как /worksheet/search/broken-links для того же листа — ссылки проверяются по всему листу. Соответственно ограничьте свои reports (или отфильтруйте полученный список по позиции), а не предполагайте, что диапазон сужает проверку.

Ни один из этих пунктов не является блокирующим фактором — они представляют собой разницу между функцией, которая «работает в демо», и той, которая предсказуемо работает в продакшене.


10. Обработка ошибок и эксплуатационные замечания

Контракт, который документирует контроллер

Статус Значение Типичная причина
400 Некорректный запрос Недопустимый URL/параметры — например, некорректный cellArea, или отсутствующий searchText
401 Неавторизован Не удалось выполнить аутентификацию или не предоставлены действительные учетные данные
404 Не найдено Исходный файл недоступен в облачном хранилище
500 Ошибка сервера Сервис столкнулся с аномалией при получении данных электронной таблицы

Внутри каждое действие оборачивает свою работу в вспомогательный класс (WorkbookElementOperation, UpdateWorkbookElementOperation, UpdateWorkbookElementOperationAndSave), который перехватывает ошибки и повторно бросает их как CellsApiException с префиксом имени операции — например SearchContentInRemoteRange Error Message: .... Это имя операции — строка, которую вы увидите в своих журналах:

Название операции Семейство конечных точек
SearchSpreadsheetContent, SearchContentInRemoteSpreadsheet Локальный / удалённый поиск
SearchContentInRemoteWorksheet, SearchContentInRemoteRange Поиск в ограниченной области удалённого
ReplaceSpreadsheetContent Локальная замена (результат в виде потоков)
ReplaceContentInRemoteSpreadsheet, ReplaceContentInRemoteWorksheet, ReplaceContentInRemoteRange Удалённая замена (сохраняет результат)
SearchSpreadsheetBrokenLinks, SearchBrokenLinksInRemoteSpreadsheet, SearchBrokenLinksInRemoteWorksheet, SearchBrokenLinksInRemoteRange Проверка ссылок

Необязательные параметры, доступные в SDK

Помимо задокументированных параметров, модели запросов облачного хранилища содержат одинаковые три необязательных настройки:

  • password — открыть книгу, защищённую паролем (поиск не требует прав записи, поэтому файлы, защищённые только от чтения, работают нормально);
  • storageName — указать пользовательское/присоединённое облачное хранилище вместо хранилища по умолчанию (Python: storage_name);
  • regoin — настройка региона/локали, используемая при интерпретации книги (Python использует region).

Authentication

Все SDK автоматически аутентифицируются с помощью OAuth 2.0 client_credentials и JWT; при использовании чистого cURL сначала вызовите /connect/token один раз (см. §4, ①).


11. Почему Aspose.Cells Cloud для поиска и замены?

  • ✅ Нулевые локальные зависимости — без Office/Excel, без COM, без хоста скриптов. Вызывается из любого языка, любой платформы (Linux, контейнеры, безсерверные);
  • ✅ Глубже, чем поиск по тексту — ячейки, формы и гиперссылки являются полноценными целями сопоставления, именно там, где реальные таблицы хранят своё содержимое;
  • ✅ Операции с областью — workbook / worksheet / range, так что можно исправить одну область одного листа без переписывания 50 MB файла;
  • ✅ Облачный или безсостояний — файлы, уже находящиеся в хранилище, никогда не покидают его; операции локальной загрузки ничего не сохраняют;
  • ✅ Точное переписывание — замены применяются через Aspose.Cells engine и повторно сериализуются, поэтому формулы, стили, диаграммы и форматирование сохраняются после обратного преобразования;
  • ✅ Одна форма во всех SDK — cURL, .NET, Python и Java поверхности отображаются 1:1, поэтому шаблон, скопированный из одного языка, работает и в остальных.

Начните сейчас: зарегистрируйтесь на Aspose Cloud Dashboard, создайте приложение, вставьте свои учетные данные в любой фрагмент выше и укажите его на одну из ваших собственных книг — вы получите работающий аудит контента за несколько минут.

Найдёте это полезным? Поставьте звёздочку, добавьте в закладки или поделитесь — и расскажите в комментариях, для чего вы используете поиск и замену в рабочей книге.