見つけて、修正して、検証する: Aspose.Cells Cloud の検索、置換 & 壊れたリンク API 完全ガイド (.NET / Python / Java / cURL)

“どの 400 の予算ワークブックがまだ Old Vendor Ltd と表示していますか?” “このテンプレート内のすべての {{COMPANY}} プレースホルダーを置き換えてください。” “私たちのレポートの中で、昨年廃止したドメインにまだリンクしているものはありますか?” — 3つの全く異なる質問、共通の答えは: クラウド上でスプレッドシートを読み書きする REST 呼び出しで、どこにも Excel がインストールされていません。

スプレッドシートの content の問題は、データが多いほぼすべてのコードベースで発生します:

  • コンテンツ監査 — すべてのセル、シェイプ、またはハイパーリンクで、廃止された製品名、古いオフィス住所、または古くなった法人名が言及されているものを見つける;
  • テンプレートレンダリング — ワークブックを顧客に送る前に、シート全体の {{PLACEHOLDER}} トークンを埋める;
  • リンクロット — コンプライアンスまたはアーカイブ作業が承認する前に、ワークブックに埋め込まれた URL がまだ解決できるか確認する;
  • 一括修正 — 数十のシートにまたがるタイプミスや誤字の列値を修正する、または特定のシートの特定領域に限定して修正する;

従来のオプション — 自分のマシン上で動作するスクリプトライブラリ、Excel マクロ、または Windows サーバー上の COM コンポーネント — はすべて、スプレッドシート ロジックを自分でホストしスケーリングすることを意味します。Aspose.Cells Cloud はそれをシンプルな REST に変換します: ファイル(またはファイル名だけ)を送信し、マッチ — または修正されたファイル — を受け取ります。

この投稿では、Aspose.Cells Cloud マイクロサービスのコア SearchController が公開する API を解説します(ソース: src/Aspose.Cells.Cloud.MicroService/Controllers/SearchController.cs)。cURL と C# (.NET) の実行可能なサンプルと、Python および Java ユーザー向けの注意点も掲載しています。


1. SearchController は何ができますか?

SearchController は 3 つの機能ファミリー をカバーし、各ファミリーは複数の スコープ で利用可能です:

ファミリー 機能の説明 ワークブックを変更しますか?
検索 クエリに一致するテキスト項目を返します — それらのシートおよびセル/シェイプ/ハイパーリンクの位置とともに いいえ
置換 一致したテキストを置換し、修正されたファイルをストリームで返すか、クラウドストレージに保存します はい
壊れたリンク http(s) ハイパーリンクをワークブック内ですべて検証し、解決できなかったものを返します いいえ

各ファミリーは 4 つのスコープ で公開されており、エンドポイントリストが長くなるのはそこです:

スコープ 検索 置換 壊れたリンク
ローカルファイル → オンライン処理(リクエスト本文にアップロード) 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

ワークブック内の すべてのテキスト項目 をダンプする2つのボーナスエンドポイントが追加されました — 詳細は §4 をご覧ください:

Goal Endpoint
クラウドファイル内のすべてのテキスト項目 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 ではないためです。

2つの操作モードとそれが重要な理由

コントローラは各アクションにデコレートを付け、デコレータはファイルがどこから来たかを正確に示します:

  • [OnlineOperation] — ステートレス。リクエストボディ(multipart)にワークブックをアップロードし、サーバーはメモリ内で処理し、クラウドストレージに何も保存されません。「このファイルに何が入っているか教えて」やワンショットテンプレートに最適です。
  • [CloudFileOperation] — ストレージバックド。サーバーはクラウドストレージから {name} を取得し(必要に応じて folder= の下)、処理を行い、置換操作の場合は結果を直接書き戻します。データはローカルマシンに転送されません。

その唯一の区別と、{worksheet} / {cellArea} ルート セグメントが、全体のメンタルモデルです。この投稿の残りは単に詳細です。


2. 実際に解析するレスポンスモデル

両方の検索ファミリーは、小さくて平坦で、バインドしやすい形状を返します。Search は 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"
    }
  ]
}

すぐに指摘すべき点が2つあります:

  1. Position はタグ付きの位置、単なるセルアドレスではありません。Cell:、Hyperlink:、または Shape: がプレフィックスとして付けられ、単一のフラットリストがマッチした 何の種類のもの を示す方法です。そのタグが「fix cell B7」と「fix the text box sitting over B7」の違いを生みます。
  2. 両方のモデルはレポート用に自己記述的 — Filename と Worksheet はすべての項目で返されるため、複数のブックをスキャンしても、後処理なしで 1 つの監査テーブルに結合できます。

3. 開始する前に必要な2つのこと

  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でも同様に動作します(以下参照)。search/replace/broken-link ファミリーは、型付けされた 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"

2 つのクエリ パラメータを使用して、1 つのシート全体、またはシート内の特定の領域に絞り込みます:

# 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(地域/ロケール設定)も公開しています — クラウドストレージのバリアントで storageName として見ることができる同じオプションパラメータです。なお、.NET SDK は regoin の綴りを保持していますが、Python SDK は同じ2つの設定を password と region と呼びます。

③ Python / Java

Python SDK は同じエンドポイント ファミリーをラップし、リクエストモデル フィールドは C# のものと 1 対 1 でマッピングされますが、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 が完全な契約です — マルチパート フィールドは単にファイル名を含める必要があります。サービスはファイル名からブックブックの名前(したがってその形式)を導き出すためです。


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"));

なぜ1つではなく3つのエンドポイントがあるのか? ルートがスコープを保持しているからです。whole-workbook エンドポイントは名前とクエリを受け取り、worksheet エンドポイントはワークシート セグメントを受け取り、range エンドポイントはワークシート と 範囲セグメントを受け取ります。これはクリーンでキャッシュ可能な REST 形状であり、“検索を絞り込む” パラメータ(worksheet、cellArea)が local-file endpoint にのみ存在することを意味します。これは、あるスコープから別のスコープへ呼び出しを移行する際に覚えておく価値があります。

6. シナリオ C: ワークブック内の すべての テキスト項目を取得

時には検索語がないことがあります — 在庫が欲しい場合です。all-textitems エンドポイントはワークブック内の すべての テキスト項目を返すので、2つのリビジョンを比較したり、翻訳用語集を作成したり、インデクサに供給したりできます:

# 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 の 2 つのスコープ パラメータが利用可能です。これにより、テンプレートの他の部分に触れずに、1 つのシートでプレースホルダーをレンダリングできます。

② クラウドワークブック内で置換し、その場で永続化する

# 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: 他の人が見つける前に壊れたリンクを探す

リンクチェックはここでの隠れた機能です — 自分で書くのは面倒で、スキップすると恥ずかしいようなものです。すべての 4 つのスコープが利用可能で、ローカルファイル バリアントが最も手軽な妥当性チェックです:

# 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 を読むと、検索は各ワークシートで 3 つの異なる要素タイプ を歩きます:

Element type Source What’s matched Position tag
セル文字列 worksheet.Cells セルの文字列値 Cell:A1
ハイパーリンク worksheet.Hyperlinks リンクの アドレス と その 表示テキスト Hyperlink:Sheet1!B4
シェイプ worksheet.Shapes shape.Text — テキストボックス、コールアウト、ラベル Shape:TextBox 3

そして、設計を行う前に知っておくべき動作は次のとおりです:

文字列セルのみが検索対象です。 スキャンは CellValueType.IsString でフィルタリングします。数値、日付、または ブール値 を保持するセルはスキップされます — したがって 2025 の検索は、シリアル値が偶然 2025 である日付形式のセルと一致しません。数式がテキストに評価されるセルは、値のタイプが文字列であるため 一致します。

大文字小文字の区別が唯一のマッチングオプションです。 ignoringCase は InvariantCultureIgnoreCase と InvariantCulture の比較を切り替えます — それだけです。生成された API ドキュメントが示唆するように、全単語、正規表現、または「セル全体の値にマッチ」モードはありません。これらのセマンティクスが必要な場合は、all-textitems インベントリを取得し、側でフィルタリングしてください。

Replace は単純で大文字小文字を区別するリテラル置換です。 Search の ignoringCase フラグには Replace では同等のものがありません — 置換パスには大文字小文字を区別しないパラメータがまったくありません。 そして、2 つのコードパスは内部で異なります。全ワークシートの置換はエンジンの Worksheet.Replace(...) に委譲されるのに対し、範囲スコープの置換は範囲を反復し、各文字列セルを cell.StringValue.Replace(...) で書き換えます。 実際の結果として、範囲スコープの置換は文字列セルのみを対象にします、そしてこれはパターンベースではなくリテラルです。

ハイパーリンクの一致はキャプションではなくアドレスを報告します。 検索がハイパーリンクの 表示テキスト と一致した場合、返される Content は依然として hyperlink.Address です。 「ここで見つけました」レポートを生成する場合は、URL が期待されます — キャプションは返されません。

壊れたリンクのチェックは http:// と https:// のみを対象とします。 mailto: リンク、ローカルファイルパス、内部の #Sheet1!A1 アンカーは完全にスキップされます — テストされないため、結果に表示されることはありません。 それはセルだけでなく シェイプ に添付されたハイパーリンクもスキャンし、死んだリンクが隠れやすい場所です。 壊れたリンクの Position は生の hyperlink.Area から構築されることに注意してください(検索エンドポイントが使用する、よりフレンドリーな Area.ToRangName() ではありません)。したがって、2 つのファミリーが位置を同一にレンダリングすると想定しないでください — 安定したキーが必要な場合は Worksheet と LinkAddress のペアを解析してください。

“Broken” は「到達不能」を意味し、「ステータスコードが間違っている」ことを意味しません。 このチェックはリンクごとに HTTP HEAD リクエストを送信し、404 や 500 を含む 任意の 応答をアクセス可能とみなします。リクエストが throws(DNS 失敗、接続拒否、TLS エラー、タイムアウト)したときだけリンクを broken とマークします。したがって、出力は 「連絡できなかったリンク」 として扱ってください。実際に必要なのが「2xx を返さないリンク」なら、返された LinkAddress の値を自分で再確認する必要があります。

cellArea は受け入れられますが、broken-link エンドポイントでは適用されません。 BrokenLinks の実装はワークシート名のみでフィルタリングします。cell-area 引数は渡されますが使用されません。実際には、.../ranges/A1:F40/search/broken-links は現在、同じワークシートに対して /worksheet/search/broken-links と同じ動作をします — リンクはシート全体で検証されます。チェック範囲が狭められると想定せず、レポート の範囲を適切に設定するか(または位置で返されたリストをフィルタリングする)ようにしてください。

これらはどれもブロッカーではありません — それらは「works in the demo」という機能と、本番環境で予測可能に動作する機能との違いです。


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 が公開するオプション パラメータ

文書化されたパラメーター以外に、クラウドストレージのリクエストモデルはすべて同じ3つのオプション設定を持っています。

  • password — パスワードで保護されたブックを開く(検索は書き込み権限を必要としないため、読み取り保護されたファイルでも問題なく動作します);
  • storageName — デフォルトではなく、カスタム/添付されたクラウドストレージを対象とする(Python: storage_name);
  • regoin — ブックを解釈する際に使用されるリージョン/ロケール設定(Python では region と綴ります).

認証

すべての SDK は OAuth 2.0 の client_credentials と JWT を使用して自動的に認証します。生の cURL を使用する場合は、最初に /connect/token を一度呼び出してください(§4、① を参照)。

11. なぜ Aspose.Cells Cloud を検索と置換に使用するのか?

  • ✅ ローカル依存なし — Office/Excel、COM、スクリプトホストは不要です。任意の言語、任意のプラットフォーム(Linux、コンテナ、サーバーレス)から呼び出せます;
  • ✅ テキスト検索以上の深さ — セル、シェイプ、ハイパーリンクはすべてファーストクラスのマッチ対象であり、実際のスプレッドシートがコンテンツを保持する場所そのものです;
  • ✅ スコープされた操作 — ワークブック / ワークシート / レンジ単位で、50 MB のファイル全体を書き換えることなく、シートの特定領域だけを修正できます;
  • ✅ クラウドネイティブまたはステートレス — すでにストレージにあるファイルは決して外部に出ず、ローカルアップロード操作は何も永続化しません;
  • ✅ 高忠実度の書き換え — 置換は Aspose.Cells エンジンを通して適用され再シリアライズされるため、数式、スタイル、チャート、書式設定が往復しても保持されます;
  • ✅ SDK間で共通の形状 — cURL、.NET、Python、Java の各インターフェイスは 1:1 にマッピングされるため、ある言語でコピーしたパターンが他の言語でもそのまま機能します。

今すぐ始めましょう: Aspose Cloud Dashboard に登録し、アプリケーションを作成し、上記の任意のスニペットに資格情報を貼り付け、独自のワークブックのいずれかを指定してください — 数分で動作するコンテンツ監査が完了します。

これが役に立ちましたか?スター、ブックマーク、または共有してください — コメントで、ワークブックの検索と置換を何に使っているか教えてください。