Trabaja con pestañas

La API de Documentos de Google te permite acceder al contenido desde cualquier pestaña del documento.

¿Qué son las pestañas?

Documentos de Google cuenta con una capa organizativa llamada pestañas. Documentos permite a los usuarios crear una o más pestañas dentro de un solo documento, de manera similar a como existen pestañas en Hojas de cálculo en la actualidad. Cada pestaña tiene su propio título y ID (que se agrega a la URL). Una pestaña también puede tener pestañas secundarias, que son pestañas anidadas debajo de otra.

Cambios estructurales en la forma en que se representa el contenido del documento en el recurso de documento

En el pasado, los documentos no tenían el concepto de pestañas, por lo que el recurso Document contenía directamente todo el contenido de texto a través de los siguientes campos:

Con la jerarquía estructural adicional de las pestañas, estos campos ya no representan semánticamente el contenido de texto de todas las pestañas del documento. El contenido basado en texto ahora se representa en una capa diferente. Puedes acceder a las propiedades y al contenido de las pestañas en Documentos de Google con document.tabs, que es una lista de objetos Tab, cada uno de los cuales contiene todos los campos de contenido de texto mencionados anteriormente. En las secciones posteriores, se proporciona una breve descripción general. La representación JSON de la pestaña también proporciona información más detallada.

Cómo acceder a las propiedades de la pestaña

Accede a las propiedades de la pestaña con tab.tabProperties, que incluye información como el ID, el título y la posición de la pestaña.

Cómo acceder al contenido de texto dentro de una pestaña

El contenido real del documento dentro de la pestaña se expone como tab.documentTab. Se puede acceder a todos los campos de contenido de texto mencionados anteriormente con tab.documentTab. Por ejemplo, en lugar de usar document.body, debes usar document.tabs[indexOfTab].documentTab.body.

Jerarquía de pestañas

Las pestañas secundarias se representan en la API como un campo tab.childTabs en Tab. Para acceder a todas las pestañas de un documento, debes recorrer el “árbol” de pestañas secundarias. Por ejemplo, considera un documento que contiene una jerarquía de pestañas de la siguiente manera:

IU de Tablist que contiene tres pestañas de nivel superior, algunas de las cuales tienen pestañas secundarias

Para recuperar el Body de la pestaña 3.1.2, accederías a document.tabs[2].childTabs[0].childTabs[1].documentTab.body. Consulta los bloques de código de muestra en la sección posterior, que proporciona código de muestra para iterar en todas las pestañas de un documento.

Cambios en los métodos

Con la introducción de las pestañas, cada uno de los métodos de documentos tiene algunos cambios que pueden requerir que actualices tu código.

documents.get

De forma predeterminada, no se muestra todo el contenido de la pestaña. Los desarrolladores deben actualizar su código para acceder a todas las pestañas. El método documents.get expone un parámetro includeTabsContent que permite configurar si se proporciona el contenido de todas las pestañas en la respuesta.

  • Si includeTabsContent se establece como true, el método documents.get mostrará un recurso Document con el campo document.tabs propagado. Todos los campos de texto directamente en document (p.ej., document.body) se dejarán vacíos.
  • Si no se proporciona includeTabsContent, los campos de texto del recurso Document (p.ej., document.body) se propagarán solo con el contenido de la primera pestaña. El campo document.tabs estará vacío y no se mostrará el contenido de otras pestañas.

documents.create

El método documents.create muestra un recurso Document que representa el documento vacío que se creó. El recurso Document que se muestra propagará el contenido del documento vacío en los campos de contenido de texto del documento y en document.tabs.

document.batchUpdate

Cada Request incluye una forma de especificar las pestañas a las que se aplicará la actualización. De forma predeterminada, si no se especifica una pestaña, en la mayoría de los casos, Request se aplicará a la primera pestaña del documento. ReplaceAllTextRequest, DeleteNamedRangeRequest y ReplaceNamedRangeContentRequest son tres solicitudes especiales que, de forma predeterminada, se aplicarán a todas las pestañas.

Consulta la documentación de Request para obtener más información.

Los usuarios pueden crear vínculos internos a pestañas, favoritos y encabezados en un documento. Con la introducción de la función de pestañas, los campos link.bookmarkId y link.headingId en el recurso Link ya no pueden representar un favorito o un encabezado en una pestaña en particular del documento.

Los desarrolladores deben actualizar su código para usar link.bookmark y link.heading en las operaciones de lectura y escritura. Exponen vínculos internos con objetos BookmarkLink y HeadingLink, cada uno de los cuales contiene el ID del favorito o encabezado y el ID de la pestaña en la que se encuentra. Además, link.tabId expone vínculos internos a las pestañas.

El contenido de vínculo de una respuesta documents.get también puede variar según el parámetro includeTabsContent:

  • Si includeTabsContent se establece como true, todos los vínculos internos se expondrán como link.bookmark y link.heading. Los campos heredados ya no se usarán.
  • Si no se proporciona includeTabsContent, en los documentos que contienen una sola pestaña, los vínculos internos a favoritos o encabezados dentro de esa pestaña única se siguen exponiendo como link.bookmarkId y link.headingId. En los documentos que contengan varias pestañas, los vínculos internos se expondrán como link.bookmark y link.heading.

En document.batchUpdate, si se crea un vínculo interno con uno de los campos heredados, se considerará que el favorito o el encabezado proviene del ID de la pestaña especificado en Request. Si no se especifica ninguna pestaña, se considerará que proviene de la primera pestaña del documento.

La representación JSON de vínculo proporciona información más detallada.

Patrones de uso comunes para las pestañas

En las siguientes muestras de código, se describen varias formas de interactuar con las pestañas.

Lee el contenido de todas las pestañas del documento

El código existente que hacía esto antes de que se pudiera migrar la función de pestañas para admitirlas se configuraba en el parámetro includeTabsContent como true, se recorría la jerarquía del árbol de pestañas y se llamaba a métodos get de Tab y DocumentTab en lugar de Document. La siguiente muestra de código parcial se basa en el fragmento de Cómo extraer el texto de un documento. Muestra cómo imprimir todo el contenido de texto de cada pestaña de un documento. Este código de recorrido de pestañas se puede adaptar a muchos otros casos de uso a los que no les importa la estructura real de las pestañas.

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

Lee el contenido de la primera pestaña del documento

Esto es similar a leer todas las pestañas.

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

Realiza una solicitud para actualizar la primera pestaña

En la siguiente muestra de código parcial, se muestra cómo segmentar una pestaña específica en un Request. Este código se basa en la muestra de la guía Cómo insertar, borrar y mover texto.

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