ابحث عنه، أصلحه، تحقق منه: دليل شامل لـ 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 — إصلاح خطأ إملائي أو قيمة عمود مكتوبة بشكل خاطئ عبر عشرات الأوراق، أو محصورة في منطقة واحدة من ورقة واحدة.

الخيارات التقليدية — مكتبة سكريبت تعمل على جهازك الخاص، ماكرو إكسل، أو مكوّن COM على خادم ويندوز — كلها تعني أنك المسؤول عن استضافة وتوسيع منطق الجداول. Aspose.Cells Cloud يحول ذلك إلى REST بسيط: أرسل ملفًا (أو مجرد اسم ملف)، احصل على التطابقات — أو ملف مصحح — مرة أخرى.

تستعرض هذه المشاركة واجهات برمجة التطبيقات (APIs) التي يقدمها الـ 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] — بدون حالة. تقوم بتحميل دفتر العمل في جسم الطلب (multipart)، يقوم الخادم بمعالجته في الذاكرة، ولا يتم حفظ أي شيء في التخزين السحابي. مثالي لـ “just tell me what’s in this file” وللتصميم لمرة واحدة.
  • [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"
    }
  ]
}

هناك شيئين يستحقان الإشارة إليهما على الفور:

  1. Position هو موقع معنّى, ليس مجرد عنوان خلية. يتم إلحاقه مسبقًا بـ Cell:, Hyperlink: أو Shape:, وهذا هو الطريقة التي يمكن من خلالها لقائمة مسطحة واحدة أن تخبرك بنوع العنصر المطابق. تلك العلامة هي الفرق بين “fix cell B7” و"fix the text box sitting over B7".
  2. كلا النموذجين يصفان نفسيهما للتقارير — Filename و Worksheet يتم إرجاعهما في كل عنصر، لذا يمكن دمج فحص عبر العديد من دفاتر العمل في جدول تدقيق واحد دون معالجة لاحقة.

3. شيئين تحتاجهما قبل أن تبدأ

  1. سجّل حسابًا مجانيًا على لوحة تحكم Aspose Cloud وأنشئ تطبيقًا للحصول على Client ID و Client Secret (تقوم SDKs بتبادل هذه للحصول على 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 (إعداد المنطقة/المحلية) — نفس المعلمات الاختيارية التي ستراها في إصدارات التخزين السحابي كـ storageName. لاحظ أن SDK الخاص بـ .NET يحتفظ بتهجئة regoin؛ SDK الخاص بـ Python يطلق على الإعدادين نفسهما password و region.

③ بايثون / جافا

يُغلف 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 التي يتم إنشاؤها عبر setters:

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. السيناريو ب: البحث عن ملف موجود بالفعل في التخزين السحابي

عندما يكون دفتر العمل موجودًا بالفعل في 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 — لا شيء أكثر. لا يوجد وضع كلمة كاملة، أو تعبير نمطي (regex)، أو وضع “مطابقة قيمة الخلية بالكامل”، على الرغم مما قد تشير إليه وثائق API المولدة. إذا كنت بحاجة إلى تلك الدلالات، اسحب مخزون all-textitems وقم بفلترته من جانبك.

الاستبدال هو استبدال بسيط، حساس لحالة الأحرف، حرفي. علم ignoringCase في البحث ليس له ما يعادله في الاستبدال — مسار الاستبدال لا يحتوي على أي معلمة لتجاهل حالة الأحرف على الإطلاق. والمساران البرمجيان يختلفان داخليًا: استبدال كامل ورقة العمل يوجه إلى 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 مقبول لكنه غير مطبق على نقاط النهاية الخاصة بالروابط المكسورة. تنفيذ BrokenLinks يفلتر حسب اسم ورقة العمل فقط؛ يتم تمرير معامل نطاق الخلية لكنه لا يُستخدم أبداً. عمليًا يعني ذلك أن .../ranges/A1:F40/search/broken-links يتصرف حاليًا بنفس طريقة /worksheet/search/broken-links لنفس ورقة العمل — يتم التحقق من الروابط عبر كامل الورقة. قم بتحديد نطاق تقاريرك وفقًا لذلك (أو صَفِّ القائمة المرتجعة حسب الموقع) بدلاً من افتراض أن النطاق يضيق الفحص.

لا شيء من هذه الأمور يشكل عائقًا — إنها الفرق بين ميزة “تعمل في العرض التجريبي” وأخرى تتصرف بشكل متوقع في الإنتاج.

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 التحقق من الروابط

المعلمات الاختيارية التي تعرضها SDKs

بعيدًا عن المعلمات الموثقة، تحمل نماذج طلبات التخزين السحابي جميعها نفس الإعدادات الثلاثة الاختيارية:

  • password — افتح مصنفًا محميًا بكلمة مرور (البحث لا يتطلب صلاحية كتابة، لذا الملفات المحمية للقراءة تعمل بشكل جيد);
  • storageName — استهدف تخزينًا سحابيًا مخصصًا/مرفقًا بدلاً من التخزين الافتراضي (Python: storage_name);
  • regoin — إعداد المنطقة/المحلية المستخدم عند تفسير المصنف (Python يكتب ذلك region).

المصادقة

تقوم جميع SDKs بالمصادقة تلقائيًا باستخدام OAuth 2.0 client_credentials و JWT؛ عند استخدام cURL الخام، استدعِ /connect/token مرة واحدة أولاً (انظر §4، ①).

11. لماذا Aspose.Cells Cloud للبحث والاستبدال؟

  • ✅ صفر تبعيات محلية — لا Office/Excel، لا COM، لا مضيف سكريبت. يمكن استدعاؤه من أي لغة، أي منصة (Linux، الحاويات، بدون خادم)؛
  • ✅ أعمق من البحث النصي — الخلايا، الأشكال و الروابط التشعبية كلها أهداف مطابقة من الدرجة الأولى، وهذا هو المكان الذي تحتفظ فيه جداول البيانات الحقيقية بمحتواها؛
  • ✅ عمليات ذات نطاق محدد — المصنف / ورقة العمل / النطاق، بحيث يمكنك تعديل منطقة واحدة من ورقة واحدة دون إعادة كتابة ملف بحجم 50 ميغابايت؛
  • ✅ سحابي أصلي أو بدون حالة — الملفات الموجودة بالفعل في التخزين لا تغادرها أبداً؛ عمليات التحميل المحلي لا تحتفظ بأي شيء على الإطلاق؛
  • ✅ إعادة كتابة عالية الدقة — يتم تطبيق الاستبدالات عبر محرك Aspose.Cells وإعادة تسلسلها، لذا تبقى الصيغ، الأنماط، المخططات والتنسيق صالحة بعد الجولة؛
  • ✅ شكل واحد عبر SDKs — واجهات cURL و .NET و Python و Java تتطابق 1:1، لذا النمط الذي تنسخه من لغة واحدة يعمل في الأخرى.

ابدأ الآن: سجّل في Aspose Cloud Dashboard، أنشئ تطبيقًا، ضع بيانات الاعتماد الخاصة بك في أي مقطع شفرة أعلاه، ووجّهها إلى أحد دفاتر العمل الخاصة بك — ستحصل على تدقيق محتوى يعمل خلال دقائق.

هل وجدت هذا مفيدًا؟ ضع نجمة، أو احفظه كإشارة مرجعية، أو شاركه — وأخبرنا في التعليقات بما تستخدمه للبحث والاستبدال في المصنف.