Utiliser les onglets

L'API Google Docs vous permet d'accéder au contenu depuis n'importe quel onglet du document.

Que sont les onglets ?

Google Docs propose une couche d'organisation appelée onglets. Docs permet aux utilisateurs de créer un ou plusieurs onglets dans un même document, comme c'est le cas dans Sheets aujourd'hui. Chaque onglet possède son propre titre et son propre ID (ajoutés à l'URL). Un onglet peut également comporter des onglets enfants, qui sont des onglets imbriqués sous un autre onglet.

Modifications structurelles apportées à la représentation du contenu des documents dans la ressource de documents

Auparavant, les documents ne comportaient pas de concept d'onglets. Par conséquent, la ressource Document contenait directement l'intégralité du contenu textuel via les champs suivants:

Avec la hiérarchie structurelle supplémentaire des onglets, ces champs ne représentent plus sémantiquement le contenu textuel de tous les onglets du document. Le contenu textuel est désormais représenté dans une autre couche. Les propriétés et le contenu des onglets dans Google Docs sont accessibles avec document.tabs, qui est une liste d'objets Tab, chacun contenant tous les champs de contenu textuel mentionnés ci-dessus. Les sections suivantes fournissent un bref aperçu. La représentation JSON de l'onglet fournit également des informations plus détaillées.

Propriétés de l'onglet "Accès"

Accédez aux propriétés de l'onglet à l'aide de tab.tabProperties, qui inclut des informations telles que l'ID, le titre et le positionnement de l'onglet.

Accéder au contenu textuel d'un onglet

Le contenu réel du document dans l'onglet est exposé sous la forme tab.documentTab. Tous les champs de contenu textuel mentionnés ci-dessus sont accessibles à l'aide de tab.documentTab. Par exemple, au lieu d'utiliser document.body, vous devez utiliser document.tabs[indexOfTab].documentTab.body.

Hiérarchie des onglets

Dans l'API, les onglets enfants sont représentés par un champ tab.childTabs sur Tab. Pour accéder à tous les onglets d'un document, vous devez parcourir l'arborescence des onglets enfants. Prenons l'exemple d'un document contenant une hiérarchie d'onglets comme suit:

UI de la liste d'onglets contenant trois onglets de niveau supérieur, dont certains comportent des onglets enfants

Pour récupérer Body à partir de l'onglet 3.1.2, vous devez accéder à document.tabs[2].childTabs[0].childTabs[1].documentTab.body. Consultez les exemples de blocs de code dans la section suivante, qui fournit des exemples de code pour itérer sur tous les onglets d'un document.

Modifications apportées aux méthodes

Avec l'introduction des onglets, chacune des méthodes de document comporte quelques modifications qui peuvent vous obliger à mettre à jour votre code.

documents.get

Par défaut, tous les contenus des onglets ne sont pas renvoyés. Les développeurs doivent mettre à jour leur code pour accéder à tous les onglets. La méthode documents.get expose un paramètre includeTabsContent qui permet de configurer si le contenu de tous les onglets est fourni dans la réponse.

  • Si includeTabsContent est défini sur true, la méthode documents.get renvoie une ressource Document avec le champ document.tabs renseigné. Tous les champs de texte directement sur document (par exemple, document.body) resteront vides.
  • Si includeTabsContent n'est pas fourni, les champs de texte de la ressource Document (par exemple, document.body) ne sont remplis que par le contenu du premier onglet. Le champ document.tabs sera vide et le contenu des autres onglets ne sera pas renvoyé.

documents.create

La méthode documents.create renvoie une ressource Document représentant le document vide créé. La ressource Document renvoyée renseignera le contenu des documents vides dans les champs de contenu textuel du document, ainsi que dans document.tabs.

document.batchUpdate

Chaque Request inclut un moyen de spécifier les onglets auxquels appliquer la mise à jour. Par défaut, si aucun onglet n'est spécifié, Request est généralement appliqué au premier onglet du document. ReplaceAllTextRequest, DeleteNamedRangeRequest et ReplaceNamedRangeContentRequest sont trois requêtes spéciales qui s'appliquent par défaut à tous les onglets.

Pour en savoir plus, consultez la documentation de Request.

Les utilisateurs peuvent créer des liens internes vers des onglets, des favoris et des titres dans un document. Avec l'introduction de la fonctionnalité d'onglets, les champs link.bookmarkId et link.headingId de la ressource Link ne peuvent plus représenter un signet ni un titre dans un onglet particulier du document.

Les développeurs doivent mettre à jour leur code pour utiliser link.bookmark et link.heading dans les opérations de lecture et d'écriture. Ils exposent des liens internes à l'aide d'objets BookmarkLink et HeadingLink, chacun contenant l'ID du favori ou de l'en-tête, ainsi que l'ID de l'onglet dans lequel il se trouve. De plus, link.tabId expose des liens internes vers les onglets.

Le contenu des liens d'une réponse documents.get peut également varier en fonction du paramètre includeTabsContent:

  • Si includeTabsContent est défini sur true, tous les liens internes sont exposés en tant que link.bookmark et link.heading. Les anciens champs ne seront plus utilisés.
  • Si includeTabsContent n'est pas fourni, dans les documents contenant un seul onglet, tous les liens internes vers des signets ou des titres de cet onglet unique continuent d'être exposés en tant que link.bookmarkId et link.headingId. Dans les documents contenant plusieurs onglets, les liens internes s'affichent sous la forme link.bookmark et link.heading.

Dans document.batchUpdate, si un lien interne est créé à l'aide de l'un des anciens champs, le favori ou l'en-tête sera considéré comme provenant de l'ID de l'onglet spécifié dans Request. Si aucun onglet n'est spécifié, il sera considéré comme provenant du premier onglet du document.

La représentation JSON des liens fournit des informations plus détaillées.

Modèles d'utilisation courants des onglets

Les exemples de code suivants décrivent différentes façons d'interagir avec les onglets.

Lire le contenu des onglets de tous les onglets du document

Le code existant qui effectuait cette opération avant la fonctionnalité d'onglets peut être migré pour prendre en charge les onglets en définissant le paramètre includeTabsContent sur true, en parcourant la hiérarchie de l'arborescence des onglets et en appelant les méthodes getter à partir de Tab et DocumentTab au lieu de Document. L'exemple de code partiel suivant est basé sur l'extrait de code de la section Extraire le texte d'un document. Il montre comment imprimer tout le contenu textuel de chaque onglet d'un document. Ce code de navigation entre les onglets peut être adapté à de nombreux autres cas d'utilisation qui ne se soucient pas de la structure réelle des onglets.

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) {
  ...
}

Lire le contenu de l'onglet du premier onglet du document

Cela revient à lire tous les onglets.

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()));
}

Envoyer une requête pour mettre à jour le premier onglet

L'exemple de code partiel suivant montre comment cibler un onglet spécifique dans un Request. Ce code est basé sur l'exemple du guide Insérer, supprimer et déplacer du texte.

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();
}