Apps Script cho Google Tài liệu cho phép bạn truy cập vào nội dung từ bất kỳ thẻ nào trong tài liệu.
Thẻ là gì?
Google Tài liệu có một lớp tổ chức được gọi là thẻ. Tài liệu cho phép người dùng tạo một hoặc nhiều thẻ trong một tài liệu, tương tự như cách các thẻ hiện có trong Trang tính. Mỗi thẻ có một tiêu đề và mã nhận dạng riêng (được thêm vào trong URL). Một thẻ cũng có thể có thẻ con, là các thẻ lồng nhau bên dưới một thẻ khác.
Truy cập vào thẻ
Bạn có thể truy cập vào thuộc tính và nội dung của thẻ bằng Document.getTabs()
. Phương thức này sẽ trả về danh sách Tab
. Các phần sau đây cung cấp thông tin tổng quan ngắn gọn về lớp Tab
; Tài liệu về lớp Thẻ cũng cung cấp thêm thông tin chi tiết.
Thuộc tính thẻ
Bạn có thể truy xuất các thuộc tính thẻ bằng các phương thức như Tab.getId()
và Tab.getTitle()
.
Nội dung thẻ
Bạn có thể truy xuất nội dung tài liệu trong mỗi thẻ bằng cách sử dụng Tab.asDocumentTab()
.
Phần Thay đổi đối với cấu trúc Lớp tài liệu mô tả cách sử dụng lớp này.
Hệ phân cấp thẻ
Các thẻ con được hiển thị trong Google Apps Script thông qua Tab.getChildTabs()
.
Để truy cập nội dung từ tất cả các thẻ, bạn phải duyệt qua "cây" của các thẻ con.
Ví dụ: hãy xem xét một tài liệu chứa hệ phân cấp thẻ như sau:
Để truy cập Tab 3.1.2, bạn có thể làm như sau:
// Print the ID of Tab 3.1.2. const doc = DocumentApp.getActiveDocument(); const tab = doc.getTabs()[2].getChildTabs()[0].getChildTabs()[1]; console.log(tab.getId());
Hãy xem các khối mã mẫu trong các phần sau. Các khối này cung cấp mã mẫu để lặp lại trên tất cả các thẻ trong một tài liệu.
Các cách khác để truy xuất thẻ
Có hai cách khác để truy xuất thẻ:
Document.getTab(tabId)
: Trả về Thẻ có mã nhận dạng đã chỉ định.Document.getActiveTab()
: Truy xuất Thẻ đang hoạt động của người dùng. Chỉ hoạt động trong các tập lệnh được liên kết với một tài liệu. Các phần sau sẽ mô tả chi tiết hơn về vấn đề này.
Thay đổi đối với cấu trúc Lớp tài liệu
Trước đây, tài liệu không có khái niệm về thẻ, vì vậy, Lớp tài liệu đã hiển thị các phương thức để truy cập và sửa đổi trực tiếp nội dung văn bản của tài liệu. Các phương thức sau đây thuộc danh mục này:
Document.addBookmark(position)
Document.addFooter()
Document.addHeader()
Document.addNamedRange(name, range)
Document.getBody()
Document.getBookmark(id)
Document.getBookmarks()
Document.getFooter()
Document.getFootnotes()
Document.getHeader()
Document.getNamedRangeById(id)
Document.getNamedRanges()
Document.getNamedRanges(name)
Document.newPosition(element, offset)
Document.newRange()
Với hệ thống phân cấp cấu trúc bổ sung của các thẻ, các phương thức này không còn đại diện về ngữ nghĩa cho nội dung văn bản của tất cả các thẻ trong tài liệu nữa. Nội dung văn bản hiện sẽ được biểu thị trong một lớp khác; tất cả các phương thức văn bản nêu trên đều có thể truy cập được thông qua DocumentTab
.
Các phương thức hiện có trên lớp Document
sẽ truy cập hoặc sửa đổi nội dung từ thẻ đang hoạt động (trong các tập lệnh liên kết với một tài liệu cụ thể) hoặc thẻ đầu tiên (nếu không có thẻ đang hoạt động).
Truy cập vào nội dung văn bản trong một Thẻ cụ thể
Thay vì sử dụng các phương thức văn bản trong Document
, bạn nên sử dụng các phương thức có trong lớp DocumentTab
(có sẵn thông qua phương thức Tab.asDocumentTab()
). Ví dụ:
// Print the text from the body of the active tab. const doc = DocumentApp.getActiveDocument(); const documentTab = doc.getActiveTab().asDocumentTab(); const body = documentTab.getBody(); console.log(body.getText());
Thay đổi đối với lựa chọn của người dùng
Phương thức chọn văn bản
Lớp Document
cung cấp phương thức getter và setter để quản lý vị trí trong văn bản mà người dùng đang chọn, trong tài liệu đang hoạt động. Các phương thức này hoạt động trong ngữ cảnh của thẻ đang hoạt động của người dùng đang chạy tập lệnh.
Document.getCursor()
: Trả về vị trí con trỏ của người dùng trong thẻ đang hoạt động.Document.getSelection()
: Trả về dải ô lựa chọn của người dùng trong thẻ đang hoạt động.Document.setCursor(position)
: Đặt vị trí con trỏ của người dùng trong tài liệu đang hoạt động. Nếu Vị trí nằm trong một thẻ không hoạt động, thì thẻ đang hoạt động của người dùng cũng sẽ chuyển sang thẻ được liên kết với Vị trí đó.Document.setSelection(range)
: Đặt phạm vi lựa chọn của người dùng trong tài liệu đang hoạt động. Nếu Phạm vi nằm trong một thẻ không hoạt động, thì thẻ đang hoạt động của người dùng cũng được chuyển sang thẻ được liên kết với phạm vi đó.
Các phương thức lựa chọn thẻ và trường hợp sử dụng
Với việc giới thiệu các thẻ, bạn có thể lấy và đặt thẻ đang hoạt động của người dùng đang chạy tập lệnh. Bạn có thể thực hiện việc này bằng các phương thức sau:
Document.getActiveTab()
: Trả vềTab
đang hoạt động của người dùng trong tài liệu đang hoạt động.Document.setActiveTab(tabId)
: ĐặtTab
đã chọn của người dùng trong tài liệu hiện tại thành thẻ có mã nhận dạng được chỉ định.
"Lựa chọn" toàn diện của người dùng được tạo thành từ sự kết hợp của thẻ đang hoạt động cùng với vị trí con trỏ hiện tại hoặc phạm vi lựa chọn. Hai mẫu để xử lý lựa chọn đang hoạt động là sửa đổi rõ ràng thẻ đang hoạt động của người dùng thành một thẻ cụ thể hoặc sử dụng thẻ đang hoạt động của người dùng.
Bạn có thể thay đổi rõ ràng thẻ đang hoạt động của người dùng bằng cách sử dụng Document.setActiveTab(tabId)
.
Ngoài ra, việc gọi Document.setCursor(position)
hoặc Document.setSelection(range)
với Position
hoặc Range
từ một thẻ không hoạt động sẽ khiến thẻ đó mới hoạt động.
Nếu hành vi dự kiến của tập lệnh là sử dụng thẻ đang hoạt động của người dùng mà không thay đổi thẻ đó, thì bạn không cần sử dụng Document.setActiveTab(tabId)
. Các phương thức Document.getCursor()
và Document.getSelection()
sẽ hoạt động trên thẻ đang hoạt động, dựa trên thẻ mà người dùng đang chạy tập lệnh.
Xin lưu ý rằng một tài liệu không hỗ trợ nhiều lựa chọn thẻ hoặc nhiều vị trí hoặc dải ô trên các thẻ khác nhau. Do đó, việc sử dụng Document.setActiveTab(tabId)
sẽ xoá vị trí con trỏ hoặc phạm vi lựa chọn trước đó.
Phương pháp vị trí và dải ô cho một Thẻ cụ thể
Thẻ cụ thể là yếu tố mang lại ý nghĩa cho các khái niệm lựa chọn văn bản của Position
và Range
. Nói cách khác, vị trí con trỏ hoặc dải ô được chọn chỉ có ý nghĩa nếu tập lệnh biết chính xác thẻ chứa vị trí hoặc dải ô đó.
Bạn có thể thực hiện việc này bằng cách sử dụng các phương thức DocumentTab.newPosition(element, offset)
và DocumentTab.newRange()
. Các phương thức này tạo Vị trí hoặc Phạm vi nhắm mục tiêu đến DocumentTab
cụ thể mà phương thức được gọi từ đó. Ngược lại, Document.newPosition(element, offset)
và Document.newRange()
sẽ tạo một Vị trí hoặc Phạm vi nhắm đến thẻ đang hoạt động (hoặc thẻ đầu tiên, nếu tập lệnh không được liên kết).
Hãy xem các khối mã mẫu trong các phần sau. Các khối này cung cấp mã mẫu để xử lý các lựa chọn.
Dạng sử dụng phổ biến cho thẻ
Các mã mẫu sau đây mô tả nhiều cách tương tác với thẻ.
Đọc nội dung thẻ từ tất cả thẻ trong tài liệu
Bạn có thể di chuyển mã hiện có đã thực hiện việc này trước tính năng thẻ để hỗ trợ thẻ bằng cách truyền tải cây thẻ và gọi phương thức getter từ Tab
và DocumentTab
thay vì Document
. Mẫu mã một phần sau đây cho biết cách in tất cả nội dung văn bản từ mọi thẻ trong một tài liệu. Bạn có thể điều chỉnh mã di chuyển qua thẻ này cho nhiều trường hợp sử dụng khác không quan tâm đến cấu trúc thực tế của các thẻ.
/** Logs all text contents from all tabs in the active document. */ function logAllText() { // Generate a list of all the tabs in the document, including any // nested child tabs. DocumentApp.openById('abc123456') can also // be used instead of DocumentApp.getActiveDocument(). const doc = DocumentApp.getActiveDocument(); const allTabs = getAllTabs(doc); // Log the content from each tab in the document. for (const tab of allTabs) { // Get the DocumentTab from the generic Tab object. const documentTab = tab.asDocumentTab(); // Get the body from the given DocumentTab. const body = documentTab.getBody(); // Get the body text and log it to the console. console.log(body.getText()); } } /** * Returns a flat list of all tabs in the document, in the order * they would appear in the UI (i.e. top-down ordering). Includes * all child tabs. */ function getAllTabs(doc) { const allTabs = []; // Iterate over all tabs and recursively add any child tabs to // generate a flat list of Tabs. for (const tab of 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. */ function addCurrentAndChildTabs(tab, allTabs) { allTabs.push(tab); for (const childTab of tab.getChildTabs()) { addCurrentAndChildTabs(childTab, allTabs); } }
Đọc nội dung thẻ từ thẻ đầu tiên trong tài liệu
Thao tác này tương tự như việc đọc tất cả các thẻ.
/** * Logs all text contents from the first tab in the active * document. */ function logAllText() { // Generate a list of all the tabs in the document, including any // nested child tabs. const doc = DocumentApp.getActiveDocument(); const allTabs = getAllTabs(doc); // Log the content from the first tab in the document. const firstTab = allTabs[0]; // Get the DocumentTab from the generic Tab object. const documentTab = firstTab.asDocumentTab(); // Get the body from the DocumentTab. const body = documentTab.getBody(); // Get the body text and log it to the console. console.log(body.getText()); }
Cập nhật nội dung thẻ trong thẻ đầu tiên
Phần mã mẫu sau đây cho biết cách nhắm đến một thẻ cụ thể khi cập nhật.
/** Inserts text into the first tab of the active document. */ function insertTextInFirstTab() { // Get the first tab's body. const doc = DocumentApp.getActiveDocument(); const firstTab = doc.getTabs()[0]; const firstDocumentTab = firstTab.asDocumentTab(); const firstTabBody = firstDocumentTab.getBody(); // Append a paragraph and a page break to the first tab's body // section. firstTabBody.appendParagraph("A paragraph."); firstTabBody.appendPageBreak(); }
Cập nhật nội dung thẻ trong thẻ đang hoạt động hoặc đã chọn
Mã mẫu một phần sau đây cho biết cách nhắm mục tiêu thẻ đang hoạt động khi cập nhật.
/** * Inserts text into the active/selected tab of the active * document. */ function insertTextInActiveTab() { // Get the active/selected tab's body. const doc = DocumentApp.getActiveDocument(); const activeTab = doc.getActiveTab(); const activeDocumentTab = activeTab.asDocumentTab(); const activeTabBody = activeDocumentTab.getBody(); // Append a paragraph and a page break to the active tab's body // section. activeTabBody.appendParagraph("A paragraph."); activeTabBody.appendPageBreak(); }
Đặt vị trí con trỏ hoặc dải ô được chọn trong thẻ đang hoạt động
Phần mã mẫu sau đây cho biết cách cập nhật vị trí con trỏ hoặc phạm vi lựa chọn trong thẻ đang hoạt động của người dùng. Điều này chỉ liên quan trong các tập lệnh ràng buộc.
/** * Changes the user's selection to select all tables within the tab * with the provided ID. */ function selectAllTables(tabId) { const doc = DocumentApp.getActiveDocument(); const tab = doc.getTab(tabId); const documentTab = tab.asDocumentTab(); // Build a range that encompasses all tables within the specified // tab. const rangeBuilder = documentTab.newRange(); const tables = documentTab.getBody().getTables(); for (let i = 0; i < tables.length; i++) { rangeBuilder.addElement(tables[i]); } // Set the document's selection to the tables within the specified // tab. Note that this actually switches the user's active tab as // well. doc.setSelection(rangeBuilder.build()); }
Đặt thẻ đang hoạt động hoặc thẻ đã chọn
Mã mẫu một phần sau đây cho biết cách thay đổi thẻ đang hoạt động của người dùng. Điều này chỉ có liên quan trong các tập lệnh liên kết.
/** * Changes the user's selected tab to the tab immediately following * the currently selected one. Handles child tabs. * *Only changes the selection if there is a tab following the
* currently selected one. */ function selectNextTab() { const doc = DocumentApp.getActiveDocument(); const allTabs = getAllTabs(doc); const activeTab = doc.getActiveTab(); // Find the index of the currently active tab. let activeTabIndex = -1; for (let i = 0; i < allTabs.length; i++) { if (allTabs[i].getId() === activeTab.getId()) { activeTabIndex = i; } } // Update the user's selected tab if there is a valid next tab. const nextTabIndex = activeTabIndex + 1; if (nextTabIndex < allTabs.length) { doc.setActiveTab(allTabs[nextTabIndex].getId()); } }