التعامل مع علامات التبويب

تتيح لك Google Docs API الوصول إلى المحتوى من أي علامة تبويب في المستند.

ما هي علامات التبويب؟

تتضمّن "مستندات Google" طبقة تنظيمية تُعرف باسم علامات التبويب. تتيح "مستندات Google" للمستخدمين إنشاء علامة تبويب واحدة أو أكثر ضمن مستند واحد، على غرار علامات التبويب المتوفّرة حاليًا في "جداول بيانات Google". لكل علامة تبويب عنوان ومعرّف خاصان بها (يتم إلحاق المعرّف بعنوان URL). يمكن أن تتضمّن علامة التبويب أيضًا علامات تبويب فرعية، وهي علامات تبويب متداخلة ضمن علامة تبويب أخرى.

تغييرات بنيوية على طريقة تمثيل محتوى المستند في "عنصر المستند"

في السابق، لم تكن المستندات تتضمّن مفهوم علامات التبويب، لذا كان Document Resource يحتوي مباشرةً على كل محتويات النص من خلال الحقول التالية:

مع التسلسل الهرمي الإضافي لعلامات التبويب، لم تعُد هذه الحقول تمثّل دلاليًا محتوى النص من جميع علامات التبويب في المستند. يتم الآن تمثيل المحتوى المستند إلى النص في طبقة مختلفة. يمكن الوصول إلى خصائص علامات التبويب والمحتوى في "مستندات Google" باستخدام document.tabs، وهي قائمة بعناصر Tab، يحتوي كل منها على جميع حقول المحتوى النصي المذكورة أعلاه. تقدّم الأقسام اللاحقة نظرة عامة موجزة، كما يوفّر تمثيل JSON لعلامة التبويب معلومات أكثر تفصيلاً.

الوصول إلى خصائص علامة التبويب

يمكنك الوصول إلى سمات علامة التبويب باستخدام tab.tabProperties، التي تتضمّن معلومات مثل رقم التعريف والعنوان والموضع الخاص بعلامة التبويب.

الوصول إلى محتوى نصي ضمن علامة تبويب

يتم عرض المحتوى الفعلي للمستند داخل علامة التبويب على النحو التالي: tab.documentTab. يمكن الوصول إلى جميع حقول المحتوى النصي المذكورة أعلاه باستخدام tab.documentTab. على سبيل المثال، بدلاً من استخدام document.body، عليك استخدام document.tabs[indexOfTab].documentTab.body.

التسلسل الهرمي لعلامات التبويب

يتم تمثيل علامات التبويب الفرعية في واجهة برمجة التطبيقات كحقل tab.childTabs ضمن Tab. يتطلّب الوصول إلى جميع علامات التبويب في مستند التنقّل عبر "شجرة" علامات التبويب الفرعية. على سبيل المثال، لنفترض أنّ لديك مستندًا يتضمّن بنية علامات تبويب على النحو التالي:

واجهة مستخدم قائمة علامات التبويب التي تحتوي على ثلاث علامات تبويب من المستوى الأعلى، بعضها يحتوي على علامات تبويب فرعية

لاسترداد Body من علامة التبويب 3.1.2، عليك الوصول إلى document.tabs[2].childTabs[0].childTabs[1].documentTab.body. اطّلِع على نماذج لكتل الرموز البرمجية في القسم التالي الذي يقدّم رمزًا برمجيًا نموذجيًا للتكرار على مستوى جميع علامات التبويب في مستند.

التغييرات في الطرق

مع تقديم علامات التبويب، تم إجراء بعض التغييرات على كلّ من طرق المستندات، وقد يتطلّب ذلك تعديل الرمز.

documents.get

بشكل تلقائي، لا يتم عرض كل محتوى علامات التبويب. على المطوّرين تعديل الرمز البرمجي الخاص بهم للوصول إلى جميع علامات التبويب. تعرض الطريقة documents.get المَعلمة includeTabsContent التي تتيح ضبط ما إذا كان سيتم توفير محتوى من جميع علامات التبويب في الردّ.

  • إذا تم ضبط includeTabsContent على true، ستعرض الطريقة documents.get المورد Document مع تعبئة الحقل document.tabs. ستبقى جميع حقول النص مباشرةً في document (مثل document.body) فارغة.
  • في حال عدم توفير includeTabsContent، سيتم ملء حقول النص في مورد Document (مثل document.body) بالمحتوى من علامة التبويب الأولى فقط. سيكون الحقل document.tabs فارغًا ولن يتم عرض المحتوى من علامات التبويب الأخرى.

documents.create

تعرض الطريقة documents.create Document Resource الذي يمثّل المستند الفارغ الذي تم إنشاؤه. سيتم ملء محتوى المستند الفارغ في كل من حقول محتوى النص في المستند وdocument.tabs باستخدام مورد Document الذي تم عرضه.

document.batchUpdate

يتضمّن كل Request طريقة لتحديد علامات التبويب التي سيتم تطبيق التحديث عليها. بشكلٍ تلقائي، إذا لم يتم تحديد علامة تبويب، سيتم تطبيق Request في معظم الحالات على علامة التبويب الأولى في المستند. ReplaceAllTextRequest وDeleteNamedRangeRequest وReplaceNamedRangeContentRequest هي ثلاثة طلبات خاصة سيتم تطبيقها تلقائيًا على جميع علامات التبويب بدلاً من ذلك.

يُرجى الرجوع إلى مستندات Requests للحصول على التفاصيل.

يمكن للمستخدمين إنشاء روابط داخلية إلى علامات التبويب والإشارات المرجعية والعناوين في المستند. مع طرح ميزة علامات التبويب، لم يعُد بإمكان الحقلَين link.bookmarkId وlink.headingId في مورد Link تمثيل إشارة مرجعية أو عنوان في علامة تبويب معيّنة في المستند.

على المطوّرين تعديل الرمز البرمجي لاستخدام link.bookmark وlink.heading في عمليات القراءة والكتابة. تعرض هذه التطبيقات الروابط الداخلية باستخدام العنصرين BookmarkLink وHeadingLink، ويحتوي كل منهما على معرّف الإشارة المرجعية أو العنوان ومعرّف علامة التبويب التي يقع فيها. بالإضافة إلى ذلك، يعرض link.tabId روابط داخلية إلى علامات التبويب.

يمكن أن تختلف محتويات الرابط في رد documents.get أيضًا استنادًا إلى المَعلمة includeTabsContent:

  • إذا تم ضبط includeTabsContent على true، سيتم عرض جميع الروابط الداخلية على النحو link.bookmark وlink.heading. لن يتم استخدام الحقول القديمة بعد الآن.
  • في حال عدم توفير includeTabsContent، سيستمر عرض أي روابط داخلية تؤدي إلى إشارات مرجعية أو عناوين ضمن علامة التبويب الفردية في المستندات التي تحتوي على علامة تبويب واحدة على النحو link.bookmarkId وlink.headingId. في المستندات التي تحتوي على علامات تبويب متعددة، سيتم عرض الروابط الداخلية على النحو التالي: link.bookmark وlink.heading.

في document.batchUpdate، إذا تم إنشاء رابط داخلي باستخدام أحد الحقول القديمة، سيتم اعتبار الإشارة المرجعية أو العنوان من معرّف علامة التبويب المحدّد في Request. في حال عدم تحديد علامة تبويب، سيتم اعتبارها من علامة التبويب الأولى في المستند.

يوفّر تمثيل JSON للرابط معلومات أكثر تفصيلاً.

أنماط الاستخدام الشائعة لعلامات التبويب

توضّح نماذج الرموز التالية طرقًا مختلفة للتفاعل مع علامات التبويب.

قراءة محتوى علامة التبويب من جميع علامات التبويب في المستند

يمكن نقل الرمز الحالي الذي كان ينفّذ هذه العملية قبل توفّر ميزة علامات التبويب، وذلك لتفعيل علامات التبويب من خلال ضبط المَعلمة includeTabsContent على true، وتتبُّع التسلسل الهرمي لشجرة علامات التبويب، واستدعاء طرق الحصول على البيانات من Tab وDocumentTab بدلاً من Document. يستند نموذج الرمز الجزئي التالي إلى المقتطف الوارد في استخراج النص من مستند. يوضّح هذا المثال كيفية طباعة كل محتوى النص من كل علامة تبويب في مستند. يمكن تكييف رمز التنقّل بين علامات التبويب هذا مع العديد من حالات الاستخدام الأخرى التي لا تهتم بالبنية الفعلية لعلامات التبويب.

Java

/** Prints all text contents from all tabs in the document. */
static void printAllText(Docs service, String documentId) throws IOException {
  // Fetch the document with all of the tabs populated, including any nested
  // child tabs.
  Document doc =
      service.documents().get(documentId).setIncludeTabsContent(true).execute();
  List<Tab> allTabs = getAllTabs(doc);

  // Print the content from each tab in the document.
  for (Tab tab: allTabs) {
    // Get the DocumentTab from the generic Tab.
    DocumentTab documentTab = tab.getDocumentTab();
    System.out.println(
        readStructuralElements(documentTab.getBody().getContent()));
  }
}

/**
 * Returns a flat list of all tabs in the document in the order they would
 * appear in the UI (top-down ordering). Includes all child tabs.
 */
private List<Tab> getAllTabs(Document doc) {
  List<Tab> allTabs = new ArrayList<>();
  // Iterate over all tabs and recursively add any child tabs to generate a
  // flat list of Tabs.
  for (Tab tab: doc.getTabs()) {
    addCurrentAndChildTabs(tab, allTabs);
  }
  return allTabs;
}

/**
 * Adds the provided tab to the list of all tabs, and recurses through and
 * adds all child tabs.
 */
private void addCurrentAndChildTabs(Tab tab, List<Tab> allTabs) {
  allTabs.add(tab);
  for (Tab tab: tab.getChildTabs()) {
    addCurrentAndChildTabs(tab, allTabs);
  }
}

/**
 * Recurses through a list of Structural Elements to read a document's text
 * where text may be in nested elements.
 *
 * <p>For a code sample, see
 * <a href="https://developers.google.com/workspace/docs/api/samples/extract-text">Extract
 * the text from a document</a>.
 */
private static String readStructuralElements(List<StructuralElement> elements) {
  ...
}

قراءة محتوى علامة التبويب من علامة التبويب الأولى في المستند

وهذا يشبه قراءة جميع علامات التبويب.

Java

/** Prints all text contents from the first tab in the document. */
static void printAllText(Docs service, String documentId) throws IOException {
  // Fetch the document with all of the tabs populated, including any nested
  // child tabs.
  Document doc =
      service.documents().get(documentId).setIncludeTabsContent(true).execute();
  List<Tab> allTabs = getAllTabs(doc);

  // Print the content from the first tab in the document.
  Tab firstTab = allTabs.get(0);
  // Get the DocumentTab from the generic Tab.
  DocumentTab documentTab = firstTab.getDocumentTab();
  System.out.println(
      readStructuralElements(documentTab.getBody().getContent()));
}

تقديم طلب لتعديل علامة التبويب الأولى

يوضّح نموذج الرمز الجزئي التالي كيفية استهداف علامة تبويب معيّنة في Request. يستند هذا الرمز إلى المثال الوارد في دليل إدراج النص وحذفه ونقله.

Java

/** Inserts text into the first tab of the document. */
static void insertTextInFirstTab(Docs service, String documentId)
    throws IOException {
  // Get the first tab's ID.
  Document doc =
      service.documents().get(documentId).setIncludeTabsContent(true).execute();
  Tab firstTab = doc.getTabs().get(0);
  String tabId = firstTab.getTabProperties().getTabId();

  List<Request>requests = new ArrayList<>();
  requests.add(new Request().setInsertText(
      new InsertTextRequest().setText(text).setLocation(new Location()
                                                            // Set the tab ID.
                                                            .setTabId(tabId)
                                                            .setIndex(25))));

  BatchUpdateDocumentRequest body =
      new BatchUpdateDocumentRequest().setRequests(requests);
  BatchUpdateDocumentResponse response =
      docsService.documents().batchUpdate(DOCUMENT_ID, body).execute();
}