עבודה עם כרטיסיות

Google Docs API מאפשר לכם לגשת לתוכן מכל כרטיסייה במסמך.

מהן כרטיסיות?

ב-Google Docs יש שכבת ארגון שנקראת כרטיסיות. ב-Docs המשתמשים יכולים ליצור כרטיסייה אחת או יותר בתוך מסמך אחד, בדומה לכרטיסיות שקיימות היום ב-Sheets. לכל כרטיסייה יש שם ומזהה משלה (שמוסיפים לכתובת ה-URL). לכרטיסייה יכולות להיות גם כרטיסיות צאצא, שהן כרטיסיות שממוקמות בתוך כרטיסייה אחרת.

שינויים מבניים באופן שבו תוכן המסמך מיוצג במשאב המסמך

בעבר, לא היה למסמכים מושג של כרטיסיות, ולכן המשאב Document הכיל ישירות את כל תוכן הטקסט באמצעות השדות הבאים:

בעקבות ההיררכיה המבנית הנוספת של הכרטיסיות, השדות האלה כבר לא מייצגים באופן סמנטי את תוכן הטקסט מכל הכרטיסיות במסמך. התוכן המבוסס על טקסט מיוצג עכשיו בשכבה אחרת. אפשר לגשת לתכנים ולמאפיינים של הכרטיסיות ב-Google Docs באמצעות document.tabs, שהיא רשימה של אובייקטים מסוג Tab, שכל אחד מהם מכיל את כל שדות תוכן הטקסט שצוינו למעלה. בקטעים הבאים מופיעה סקירה כללית קצרה, ובתיאור של Tab JSON מופיע מידע מפורט יותר.

גישה למאפייני הכרטיסייה

גישה למאפייני הכרטיסייה באמצעות tab.tabProperties, כולל מידע כמו המזהה, השם והמיקום של הכרטיסייה.

גישה לתוכן טקסט בכרטיסייה

תוכן המסמך בפועל בכרטיסייה מוצג בתור tab.documentTab. אפשר לגשת לכל שדות תוכן הטקסט שצוינו למעלה באמצעות tab.documentTab. לדוגמה, במקום להשתמש ב-document.body, צריך להשתמש ב-document.tabs[indexOfTab].documentTab.body.

היררכיית הכרטיסיות

כרטיסיות צאצא מיוצגות ב-API בתור שדה 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 שמייצג את המסמך הריק שנוצר. המשאב Document שהוחזר יאכלס את תוכן המסמך הריק בשדות תוכן הטקסט של המסמך וגם ב-document.tabs.

document.batchUpdate

כל Request כולל דרך לציין את הכרטיסיות שבהן רוצים להחיל את העדכון. כברירת מחדל, אם לא מציינים כרטיסייה, הפקודה Request תחול ברוב המקרים על הכרטיסייה הראשונה במסמך. ReplaceAllTextRequest,‏ DeleteNamedRangeRequest ו-ReplaceNamedRangeContentRequest הן שלוש בקשות מיוחדות שיוגדרו כברירת מחדל לכל הכרטיסיות.

לפרטים נוספים, עיינו במסמכי התיעוד של Request.

משתמשים יכולים ליצור קישורים פנימיים לכרטיסיות, לסימניות ולכותרות במסמך. בעקבות ההשקה של התכונה 'כרטיסיות', השדות 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, לעבור על היררכיית העץ של הכרטיסיות ולקרוא לשיטות ה-getter של 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/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();
}