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:
document.body
document.headers
document.footers
document.footnotes
document.documentStyle
document.suggestedDocumentStyleChanges
document.namedStyles
document.suggestedNamedStylesChanges
document.lists
document.namedRanges
document.inlineObjects
document.positionedObjects
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:
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 comotrue
, el métododocuments.get
mostrará un recursoDocument
con el campodocument.tabs
propagado. Todos los campos de texto directamente endocument
(p.ej.,document.body
) se dejarán vacíos. - Si no se proporciona
includeTabsContent
, los campos de texto del recursoDocument
(p.ej.,document.body
) se propagarán solo con el contenido de la primera pestaña. El campodocument.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.
Cambios en los vínculos internos
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 comotrue
, todos los vínculos internos se expondrán comolink.bookmark
ylink.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 comolink.bookmarkId
ylink.headingId
. En los documentos que contengan varias pestañas, los vínculos internos se expondrán comolink.bookmark
ylink.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(); }