찾아라, 고쳐라, 검증하라: Aspose.Cells Cloud 검색, 교체 및 깨진 링크 API에 대한 완전 가이드 (.NET / Python / Java / cURL)
“우리 400개의 예산 워크북 중 아직도 _Old Vendor Ltd_라고 표시된 것이 있나요?” “이 템플릿의 모든
{{COMPANY}}자리표시자를 교체하세요.” “우리 보고서 중 아직도 작년 퇴역한 도메인에 연결된 것이 있나요?” — 매우 다른 세 질문이지만, 공통된 답은 클라우드에서 스프레드시트를 읽고 다시 쓰는 REST 호출이며, 어디에도 Excel이 설치되어 있지 않습니다.
스프레드시트 콘텐츠 문제는 거의 모든 데이터 중심 코드베이스에서 나타납니다:
- Content audit — 사용되지 않는 제품 이름, 오래된 사무실 주소 또는 오래된 법인명을 언급하는 모든 셀, 도형 또는 하이퍼링크를 찾는 작업;
- Template rendering — 워크북을 고객에게 보내기 전에 시트 전반에 걸쳐
{{PLACEHOLDER}}토큰을 채우는 작업; - Link rot — 컴플라이언스 또는 보관 작업이 승인하기 전에 워크북에 포함된 URL이 여전히 유효한지 확인하는 작업;
- Bulk correction — 수십 개의 시트에 걸쳐 오타나 잘못 표기된 열 값을 수정하거나, 특정 시트의 한 영역에만 적용하는 작업.
전통적인 옵션 — 자체 컴퓨터에서 실행되는 스크립팅 라이브러리, Excel 매크로, 또는 Windows 서버의 COM 구성 요소 — 모두 스프레드시트 로직을 직접 호스팅하고 확장해야 함을 의미합니다. Aspose.Cells Cloud는 이를 단순한 REST로 바꿉니다: 파일(또는 파일 이름만) 전송하고, 일치 항목 — 혹은 수정된 파일 — 을 반환받습니다.
이 게시물에서는 핵심 SearchController가 Aspose.Cells Cloud 마이크로서비스에서 제공하는 API를 살펴보고 (소스: src/Aspose.Cells.Cloud.MicroService/Controllers/SearchController.cs), cURL 및 C# (.NET) 예제를 실행 가능한 형태로 제공하며, Python 및 Java 사용자를 위한 참고 사항도 포함합니다.
1. SearchController는 무엇을 할 수 있나요?
SearchController는 세 가지 기능 패밀리를 포함하며, 각각은 여러 _범위_에서 사용할 수 있습니다:`
| Family | What it does | Mutates the workbook? |
|---|---|---|
| Search | 쿼리와 일치하는 텍스트 항목을 반환하며, 해당 시트와 셀/도형/하이퍼링크 위치를 포함합니다. | 아니오 |
| Replace | 일치하는 텍스트를 교체하고, 수정된 파일을 스트리밍으로 반환하거나 클라우드 스토리지에 저장합니다. | 예 |
| Broken links | 워크북의 모든 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. 실제로 파싱하게 될 응답 모델
두 검색 패밀리는 작고 평평하며 바인딩하기 쉬운 형태를 반환합니다. 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"
}
]
}
Broken-link 검색은 **BrokenLinksResponse**를 반환합니다:
{
"Code": 200,
"Status": "OK",
"BrokenLinks": [
{
"Filename": "Book1.xlsx",
"Worksheet": "Links",
"Position": "Hyperlink:Sheet1!B4",
"LinkAddress": "https://retired-domain.example.com/report"
}
]
}
두 가지는 즉시 지적할 가치가 있습니다:
Position은 태그가 붙은 위치, 단순히 셀 주소만은 아닙니다. 앞에Cell:,Hyperlink:또는Shape:가 붙으며, 이는 단일 평면 목록이 _어떤 종류의 항목_이 일치했는지 알려주는 방식입니다. 그 태그가 “fix cell B7"과 “fix the text box sitting over B7” 사이의 차이를 만듭니다.- 두 모델은 보고를 위해 자체 설명형 —
Filename과Worksheet이 모든 항목에 반환되므로, 여러 워크북을 스캔한 결과를 후처리 없이 하나의 감사 테이블로 연결할 수 있습니다.
3. 시작하기 전에 필요한 두 가지
- 무료 계정을 Aspose Cloud Dashboard에 등록하고 애플리케이션을 생성하여
Client ID와Client Secret을 얻으세요 (SDK는 이를 자동으로 JWT로 교환하므로 인증 헤더를 직접 만들 필요가 없습니다). - 원하는 언어용 SDK를 설치하세요.
<!-- .NET -->
<PackageReference Include="Aspense.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"
두 개의 추가 쿼리 매개변수를 사용하여 하나의 시트 또는 하나의 시트 내의 특정 영역으로 범위를 좁히세요.
# 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는 동일한 두 설정을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는 setter를 통해 구축된 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"));
왜 하나가 아니라 세 개의 엔드포인트인가요? 라우트가 범위를 전달하기 때문입니다. 전체 워크북 엔드포인트는 이름과 쿼리를 받으며; 워크시트 엔드포인트는 워크시트 세그먼트를 받습니다; 범위 엔드포인트는 워크시트 및 범위 세그먼트를 받습니다. 이것은 깔끔하고 캐시 가능한 REST 구조이며 — “검색 범위 좁히기” 매개변수(
worksheet,cellArea)는 로컬 파일 엔드포인트에 오직 존재한다는 의미입니다. 이는 한 범위에서 다른 범위로 호출을 포팅할 때 기억해 두면 좋습니다.
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 비교 사이를 전환합니다 — 그 외는 없습니다. 생성된 API 문서가 암시하는 바와 달리 전체 단어, 정규식, 또는 “전체 셀 값 일치” 모드는 없습니다. 이러한 의미가 필요하다면 all-textitems 인벤토리를 가져와서 직접 필터링하십시오.
Replace는 단순하고 대소문자를 구분하는 리터럴 치환입니다. Search의 ignoringCase 플래그는 Replace에서는 동등한 것이 없습니다 — replace 경로에는 대소문자 무시 매개변수가 전혀 없습니다. 그리고 두 코드 경로는 내부적으로 다릅니다: 전체 워크시트 교체는 엔진의 Worksheet.Replace(...)에 위임하고, 범위 기반 교체는 범위를 반복하면서 각 문자열 셀을 cell.StringValue.Replace(...)로 다시 씁니다. 실용적인 결과: 범위 기반 교체는 문자열 셀만 영향을 미칩니다, 그리고 이는 패턴 기반이 아닌 리터럴 교체입니다.
하이퍼링크 일치는 주소를 보고, 캡션을 보고하지 않습니다. 검색이 하이퍼링크의 _표시 텍스트_와 일치하면, 반환되는 Content는 여전히 hyperlink.Address입니다. “여기서 찾음” 보고서를 렌더링하는 경우, URL을 기대하세요 — 캡션은 다시 반환되지 않습니다.
Broken-link 검사에서는 http://와 https://만 확인합니다. mailto: 링크, 로컬 파일 경로 및 내부 #Sheet1!A1 앵커는 완전히 건너뛰며 — 테스트되지 않으므로 결과에 나타나지 않습니다. 또한 셀뿐만 아니라 shapes에 연결된 하이퍼링크도 스캔합니다. 바로 그곳이 끊어진 링크가 숨겨지는 위치입니다. 주의할 점은 끊어진 링크 Position이 원시 hyperlink.Area에서 생성된다는 것입니다(Area.ToRangName()처럼 더 친숙한 형태가 아니라 검색 엔드포인트에서 사용됩니다). 따라서 두 패밀리가 위치를 동일하게 표시한다고 가정하지 마세요 — 안정적인 키가 필요하면 Worksheet + LinkAddress 쌍을 파싱하세요.
“Broken"는 “접근 불가"를 의미하며, “잘못된 상태 코드"를 의미하지 않습니다. 이 검사는 각 링크에 대해 HTTP HEAD 요청을 보내며 모든 응답 — 404 또는 500 포함 — 을 접근 가능으로 간주합니다; 요청이 throws(DNS 실패, 연결 거부, TLS 오류, 타임아웃)될 때만 링크를 끊어진 것으로 표시합니다. 따라서 출력은 “연락할 수 없는 링크” 로 간주하십시오. 실제로 필요로 하는 것이 “2xx를 반환하지 않는 링크"라면, 반환된 LinkAddress 값을 직접 다시 확인해야 합니다.
cellArea는 허용되지만 깨진 링크 엔드포인트에서는 적용되지 않습니다. BrokenLinks 구현은 워크시트 이름만으로 필터링합니다; 셀 영역 인자는 전달되지만 사용되지 않습니다. 실제로 이는 .../ranges/A1:F40/search/broken-links가 현재 동일 워크시트에 대해 /worksheet/search/broken-links와 동일하게 동작한다는 의미이며, 링크는 전체 시트에 대해 검증됩니다. 범위가 검사를 좁힌다고 가정하지 말고 _reports_를 해당 범위에 맞게 조정하거나(또는 반환된 목록을 위치별로 필터링) 하세요.
이 중 어느 것도 차단 요소는 아니며—이는 “데모에서 작동하는” 기능과 실제 운영 환경에서 예측 가능하게 동작하는 기능 사이의 차이점입니다.
10. 오류 처리 및 운영 메모
컨트롤러가 문서화하는 계약
| 상태 | 의미 | 일반적인 원인 |
|---|---|---|
| 400 | 잘못된 요청 | 잘못된 URL/매개변수 — 예: 잘못된 형식의 cellArea, 또는 누락된 searchText |
| 401 | 인증되지 않음 | 인증에 실패했거나 유효한 자격 증명이 제공되지 않았습니다. |
| 404 | 찾을 수 없음 | 소스 파일에 클라우드 저장소에서 접근할 수 없습니다. |
| 500 | 서버 오류 | 스프레드시트 데이터를 가져오는 중 서비스에 이상이 발생했습니다. |
내부적으로, 모든 작업은 헬퍼(WorkbookElementOperation, UpdateWorkbookElementOperation, UpdateWorkbookElementOperationAndSave)에 작업을 래핑하여 실패를 포착하고 이를 CellsApiException 작업 이름이 접두사로 붙은 형태로 다시 throw합니다 — 예를 들어 SearchContentInRemoteRange Error Message: .... 해당 작업 이름은 로그에서 볼 수 있는 문자열입니다:
| 작업 이름 | 엔드포인트 패밀리 |
|---|---|
SearchSpreadsheetContent, SearchContentInRemoteSpreadsheet |
로컬 / 원격 검색 |
SearchContentInRemoteWorksheet, SearchContentInRemoteRange |
범위 지정 원격 검색 |
ReplaceSpreadsheetContent |
로컬 교체 (스트림 결과) |
ReplaceContentInRemoteSpreadsheet, ReplaceContentInRemoteWorksheet, ReplaceContentInRemoteRange |
원격 교체 (결과 저장) |
SearchSpreadsheetBrokenLinks, SearchBrokenLinksInRemoteSpreadsheet, SearchBrokenLinksInRemoteWorksheet, SearchBrokenLinksInRemoteRange |
링크 검증 |
SDK가 노출하는 선택적 매개변수
문서화된 매개변수를 제외하고, 클라우드 스토리지 요청 모델은 모두 동일한 세 가지 선택적 설정을 포함합니다:
password— 비밀번호로 보호된 워크북을 엽니다 (검색은 쓰기 권한이 필요하지 않으므로 읽기 전용 파일도 정상 작동합니다);storageName— 기본 클라우드 스토리지가 아닌 사용자 지정/첨부된 클라우드 스토리지를 대상으로 합니다 (Python:storage_name);regoin— 워크북을 해석할 때 사용되는 지역/로케일 설정입니다 (Python에서는 이를region이라고 표기합니다).
인증
모든 SDK는 OAuth 2.0 client_credentials 및 JWT를 사용하여 자동으로 인증합니다; raw 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에서 등록하고, 애플리케이션을 생성한 다음, 위의 스니펫 중 하나에 자격 증명을 넣고, 자신의 워크북 중 하나를 지정하세요 — 몇 분 안에 작동하는 콘텐츠 감사를 받을 수 있습니다.
이 내용이 도움이 되었나요? 별표를 달거나, 북마크하거나, 공유해 보세요 — 그리고 댓글에 워크북 검색 및 교체를 어떻게 사용하고 있는지 알려주세요.