Google Docs API를 사용하면 문서의 모든 탭에서 콘텐츠에 액세스할 수 있습니다.
탭이란 무엇인가요?
Google Docs에는 탭이라는 조직 레이어가 있습니다. Docs를 사용하면 현재 Sheets에 탭이 있는 것처럼 사용자가 단일 문서 내에 하나 이상의 탭을 만들 수 있습니다. 각 탭에는 고유한 제목과 ID (URL에 추가됨)가 있습니다. 탭에는 다른 탭 아래에 중첩된 하위 탭이 있을 수도 있습니다.
문서 리소스에서 문서 콘텐츠가 표시되는 방식의 구조적 변경사항
이전에는 문서에 탭 개념이 없었으므로 Document
리소스는 다음 필드를 통해 모든 텍스트 콘텐츠를 직접 포함했습니다.
document.body
document.headers
document.footers
document.footnotes
document.documentStyle
document.suggestedDocumentStyleChanges
document.namedStyles
document.suggestedNamedStylesChanges
document.lists
document.namedRanges
document.inlineObjects
document.positionedObjects
탭의 구조적 계층 구조가 추가됨에 따라 이러한 필드는 더 이상 문서의 모든 탭의 텍스트 콘텐츠를 의미론적으로 나타내지 않습니다. 이제 텍스트 기반 콘텐츠가 다른 레이어로 표시됩니다. Google Docs의 탭 속성 및 콘텐츠는 Tab
객체 목록인 document.tabs
를 사용하여 액세스할 수 있으며, 각 객체에는 앞서 언급된 모든 텍스트 콘텐츠 필드가 포함되어 있습니다. 이후 섹션에서는 간단한 개요를 제공합니다. 탭 JSON 표현에서도 자세한 정보를 확인할 수 있습니다.
탭 속성 액세스
탭의 ID, 제목, 위치와 같은 정보가 포함된 tab.tabProperties
를 사용하여 탭 속성에 액세스합니다.
탭 내 텍스트 콘텐츠에 액세스
탭 내의 실제 문서 콘텐츠는 tab.documentTab
로 노출됩니다. 앞서 언급한 모든 텍스트 콘텐츠 필드는 tab.documentTab
를 사용하여 액세스할 수 있습니다.
예를 들어 document.body
대신 document.tabs[indexOfTab].documentTab.body
을 사용해야 합니다.
탭 계층 구조
하위 탭은 API에서 Tab
의 tab.childTabs
필드로 표현됩니다. 문서의 모든 탭에 액세스하려면 하위 탭의 '트리'를 탐색해야 합니다. 예를 들어 다음과 같이 탭 계층 구조가 포함된 문서를 살펴보겠습니다.
탭 3.1.2에서 Body
를 가져오려면 document.tabs[2].childTabs[0].childTabs[1].documentTab.body
에 액세스합니다. 문서의 모든 탭을 반복하는 샘플 코드를 제공하는 후반 섹션의 샘플 코드 블록을 참고하세요.
메서드 변경사항
탭이 도입됨에 따라 각 문서 메서드에 몇 가지 변경사항이 적용되어 코드를 업데이트해야 할 수 있습니다.
documents.get
기본적으로 일부 탭 콘텐츠만 반환됩니다. 개발자는 모든 탭에 액세스할 수 있도록 코드를 업데이트해야 합니다. documents.get
메서드는 모든 탭의 콘텐츠가 응답에 제공되는지 구성할 수 있는 includeTabsContent
매개변수를 노출합니다.
includeTabsContent
가true
로 설정되면documents.get
메서드는document.tabs
필드가 채워진Document
리소스를 반환합니다.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
리소스의 link.bookmarkId
및 link.headingId
필드는 더 이상 문서의 특정 탭에 있는 북마크나 제목을 나타낼 수 없습니다.
개발자는 읽기 및 쓰기 작업에서 link.bookmark
및 link.heading
를 사용하도록 코드를 업데이트해야 합니다. BookmarkLink
및 HeadingLink
객체를 사용하여 내부 링크를 노출하며, 각 객체에는 북마크 또는 제목의 ID와 해당 북마크 또는 제목이 있는 탭의 ID가 포함됩니다. 또한 link.tabId
는 탭에 내부 링크를 노출합니다.
documents.get
응답의 링크 콘텐츠도 includeTabsContent
매개변수에 따라 다를 수 있습니다.
includeTabsContent
이true
로 설정되면 모든 내부 링크가link.bookmark
및link.heading
로 노출됩니다. 기존 필드는 더 이상 사용되지 않습니다.includeTabsContent
이 제공되지 않으면 단일 탭이 포함된 문서에서 해당 탭 내의 북마크 또는 제목에 대한 모든 내부 링크가 계속link.bookmarkId
및link.headingId
로 노출됩니다. 탭이 여러 개 포함된 문서에서는 내부 링크가link.bookmark
및link.heading
로 노출됩니다.
document.batchUpdate
에서 기존 필드 중 하나를 사용하여 내부 링크를 만드는 경우 북마크 또는 제목은 Request
에 지정된 탭 ID에서 가져온 것으로 간주됩니다. 탭을 지정하지 않으면 문서의 첫 번째 탭에서 가져온 것으로 간주됩니다.
링크 JSON 표현에서 자세한 정보를 확인할 수 있습니다.
탭의 일반적인 사용 패턴
다음 코드 샘플은 탭과 상호작용하는 다양한 방법을 설명합니다.
문서의 모든 탭에서 탭 콘텐츠 읽기
탭 기능이 도입되기 전에 이를 실행했던 기존 코드는 includeTabsContent
매개변수를 true
로 설정하고, 탭 트리 계층 구조를 탐색하고, Document
대신 Tab
및 DocumentTab
에서 getter 메서드를 호출하여 탭을 지원하도록 이전할 수 있습니다. 다음의 일부 코드 샘플은 문서에서 텍스트 추출의 스니펫을 기반으로 합니다. 문서의 모든 탭에서 텍스트 콘텐츠를 모두 인쇄하는 방법을 보여줍니다. 이 탭 탐색 코드는 탭의 실제 구조를 고려하지 않는 다른 많은 사용 사례에 맞게 조정할 수 있습니다.
자바
/** 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) { ... }
문서의 첫 번째 탭에서 탭 콘텐츠 읽기
이는 모든 탭을 읽는 것과 유사합니다.
자바
/** 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
에서 특정 탭을 타겟팅하는 방법을 보여줍니다. 이 코드는 텍스트 삽입, 삭제, 이동 가이드의 샘플을 기반으로 합니다.
자바
/** 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(); }