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 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 duy nhất, tương tự như cách có các thẻ trong Trang tính hiện nay. Mỗi thẻ có tiêu đề và mã riêng (được thêm vào URL). Một thẻ cũng có thể có thẻ con, là những thẻ được lồng bên dưới một thẻ khác.
Thẻ truy cập
Bạn có thể truy cập vào các thuộc tính và nội dung của thẻ bằng Document.getTabs()
. Thao tác này sẽ trả về một danh sách các Tab
. Các phần sau này sẽ cung cấp thông tin tổng quan ngắn gọn về lớp Tab
; Tài liệu về lớp Tab cũng cung cấp thông tin chi tiết hơn.
Thuộc tính thẻ
Bạn có thể truy xuất các thuộc tính của 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 Các thay đổi đối với cấu trúc Lớp tài liệu mô tả cách sử dụng cấu trúc 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 vào nội dung trong tất cả các thẻ, bạn cần di chuyển 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 vào Mục 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ó 2 cách khác để truy xuất các thẻ:
Document.getTab(tabId)
: Trả về Thẻ có mã nhận dạng được chỉ định.Document.getActiveTab()
: Trả về 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 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 biểu thị một cách ngữ nghĩa nội dung văn bản từ tất cả các thẻ trong tài liệu nữa. Giờ đây, nội dung văn bả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 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 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 của Document
, bạn nên sử dụng các phương thức có sẵn của 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 các phương thức getter và setter để quản lý vị trí mà người dùng đang chọn trong văn bản, trong tài liệu đang hoạt động. Các phương thức này hoạt động trong bối cảnh của thẻ đang hoạt động của người dùng 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ề phạm vi 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 sẽ được chuyển sang thẻ được liên kết với Phạm vi đó.
Các phương thức chọn thẻ và trường hợp sử dụng
Khi các thẻ được giới thiệu, bạn nên lấy và đặt thẻ đang hoạt động của người dùng 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
mà người dùng đã chọn 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" tổng thể của người dùng bao gồm sự kết hợp giữ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 để làm việc với một 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)
bằng 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 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 thức vị trí và phạm vi cho một thẻ cụ thể
Thẻ cụ thể này giúp giải thích ý nghĩa của các khái niệm chọn văn bản Position
và Range
. Nói cách khác, vị trí con trỏ hoặc phạm vi lựa chọn chỉ có ý nghĩa nếu tập lệnh biết thẻ cụ thể mà vị trí hoặc phạm vi nằm trong đó.
Điều này được thực hiện 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 một Position hoặc Range nhắm đế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 Dải ô 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 để làm việc với các lựa chọn.
Các mẫu sử dụng thẻ phổ biến
Các mẫu mã sau đây mô tả nhiều cách tương tác với các thẻ.
Đọc nội dung thẻ từ tất cả cá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 khi có tính năng thẻ để hỗ trợ các thẻ bằng cách duyệt qua cây thẻ và gọi các phương thức getter từ Tab
và DocumentTab
thay vì Document
. Đoạn mã mẫu 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 bằng phím Tab này cho nhiều trường hợp sử dụng khác mà không cần 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 của thẻ từ thẻ đầu tiên trong tài liệu
Thao tác này tương tự như thao tá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
Đoạn mã mẫu sau đây cho biết cách nhắm đến một thẻ cụ thể khi thực hiện các bản 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 thẻ đã chọn
Đoạn mã mẫu sau đây cho biết cách nhắm đến thẻ đang hoạt động khi thực hiện các bản 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
Đoạ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ỉ phù hợp trong các tập lệnh liên kết.
/** * 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ẻ được chọn
Đoạn mã mẫu 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ỉ phù hợp với 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()); } }