如果你剛踏進 Apps Script 的世界,getName() 聽起來也許有點樸素,但它超常用:想在畫面上彈出目前文件的名稱?寄信時把文件標題放進主旨?或做一個清單列出多份文件的名稱?通通靠它。
這篇用最貼近實務的方式帶你上手:先講清楚 getName() 回傳的是什麼、什麼時候該用 getActiveDocument(),什麼時候改用 openById() 或 openByUrl();再一步步示範常見情境,像是批次列名、寄信通知、加上時間戳改名。
也不會閃躲坑洞:授權範圍要怎麼過、為什麼找不到 openByName()、遇到 .docx 檔該怎麼辦、跑很多檔案時怎麼避免超時。你只要照著貼、改兩行參數,就能跑起來。希望本篇文章能夠幫助到需要的您。
目錄
{tocify} $title={目錄}
為什麼要在專案裡用 getName()?
在自動化處理 Google 文件(Google Docs)時,我們常需要讀取目前文件的標題(也就是使用者在檔案左上角看到的名稱)。不論你是做批次報表、產生合約、建立匯出清單,或只是要把檔名寫進郵件主旨,getName() 都是最乾脆的入口。
在 Apps Script 的文件物件(DocumentApp.Document)上,getName() 會回傳該文件的標題字串。官方參考文件是這樣定義的:Retrieves the title of the document.(回傳文件標題)。
小提醒:同一個物件也支援 setName() 用於改名(設定文件標題),兩者一讀一寫,搭配起來就能做完整的檔名治理流程(下面有實作)。
getName() 跟誰一起用最順?
通常會搭配三種入口把文件「抓」進來,然後再取名:
已綁定文件(Container-bound)
用 DocumentApp.getActiveDocument() 取得當前綁定的那份文件,再 .getName()。這條路線最適合在「文件裡點選自訂選單或外掛」時使用。官方也明確說明 getActiveDocument() 是取與腳本綁在一起的那份文件。
用文件 ID 開啟
DocumentApp.openById('文件ID') → .getName()。當你的流程手上有一串 ID(像是從資料表或雲端硬碟清單來的),這是最穩定的做法。
用文件 URL 開啟
DocumentApp.openByUrl('完整URL') → .getName()。當系統裡保存的是網址而非 ID,就走這條。
權限(Scopes)會影響嗎?
會。只要你要讀取或操作 Google Docs,腳本通常需要以下其中一個 scope:
https://www.googleapis.com/auth/documents.currentonly
https://www.googleapis.com/auth/documents
這兩個在 Document 類別的多數方法(包含 getName())上都有標註。第一次執行時,Apps Script 會要求你授權。
實作步驟與範例
範例 1:讀取「目前這份」文件的名稱(綁定腳本)
適用情境:在 Google Docs 內建一個自訂選單,點了就秀文件名。
function onOpen() {
DocumentApp.getUi()
.createMenu('自動化')
.addItem('顯示文件名稱', 'showDocName')
.addToUi();
}
function showDocName() {
const doc = DocumentApp.getActiveDocument(); // 取綁定的文件
const name = doc.getName(); // 讀標題
DocumentApp.getUi().alert(`這份文件的名稱是:${name}`);
}
為什麼可行:getActiveDocument() 回傳與此腳本綁定的文件實例;getName() 讀到該實例的標題。
範例 2:用文件 ID 讀取名稱(最穩健)
function printDocNameById() {
const id = 'YOUR_DOC_ID';
const doc = DocumentApp.openById(id);
Logger.log(doc.getName());
}
何時用:你在表單回覆、試算表或資料庫裡記錄的是檔案 ID。openById() 是 Apps Script 官方推薦的「指定檔案」方式。
範例 3:用 URL 讀取名稱(來源是連結)
function printDocNameByUrl() {
const url = 'https://docs.google.com/document/d/xxxxxxxxxxxxxxxxxxxx/edit';
const doc = DocumentApp.openByUrl(url);
Logger.log(doc.getName());
}
何時用:你的系統裡保存、傳遞的是完整網址而不是 ID。
範例 4:把文件名稱拿去寄信(主旨+連結一起丟)
function emailDocLinkToMe() {
const doc = DocumentApp.getActiveDocument();
const subject = `[文件通知] ${doc.getName()}`;
const body = `這是文件連結:\n${doc.getUrl()}`;
MailApp.sendEmail(Session.getActiveUser().getEmail(), subject, body);
}
說明:getName() 拿標題,getUrl() 拿可存取的網址。官方在 getUrl() 條目也示範了把名稱與連結一起用在郵件裡。
範例 5:批次列出一整串文件名稱(從 ID 陣列來)
function listManyDocNames(ids) {
return ids.map(id => {
try {
return { id, name: DocumentApp.openById(id).getName() };
} catch (err) {
return { id, name: null, error: String(err) };
}
});
}
// 測試
function demoListManyDocNames() {
const ids = ['ID_A', 'ID_B', 'ID_C'];
const results = listManyDocNames(ids);
results.forEach(r => Logger.log(JSON.stringify(r)));
}
範例 6:讀完就改名(setName())
function renameWithTimestamp(id) {
const doc = DocumentApp.openById(id);
const oldName = doc.getName();
const newName = `${oldName} - 已歸檔 ${Utilities.formatDate(new Date(), Session.getScriptTimeZone(), 'yyyyMMdd_HHmm')}`;
doc.setName(newName); // 改標題
return { id, oldName, newName };
}
setName() 是設定「文件標題」(使用者在左上角看到的名稱)。用它能做版本標記、歸檔戳記或流程狀態追蹤。官方條目明載 Sets the document title.。
與 DriveApp 的名稱有沒有差?
多數情況下,Docs 的標題 = 雲端硬碟的檔名,所以 Document#getName() 與 DriveApp.getFileById(id).getName() 看到的會一致。實務上若你需要同時取 ID / 標題 / MIME 類型 來分流(例如排除非 Google Docs 的 .docx),就會用 DriveApp 取得檔案清單,再以 ID 交給 DocumentApp 做內容層處理。
(補充:若你想「用檔名開啟文件」,DocumentApp 沒有提供 openByName(),社群也都有相同結論——請先用 DriveApp 找到目標檔案,再拿到 ID。)
常見錯誤與雷點
1. getActiveDocument() 取不到東西或回錯文件
現象:在獨立腳本(Standalone)呼叫 getActiveDocument(),卻不是你想要的文件。
原因:
官方文件寫得很白,getActiveDocument() 回傳的是「與腳本綁定的那份文件」,不是你桌面上目前開著的任意文件。獨立腳本通常沒有綁定對象。
解法:改用 openById() 或 openByUrl() 明確指定目標。
2. 權限(Scopes)沒給,第一次執行就噴
現象:第一次執行就跳出需要授權,或被拒。
原因:文件服務需要 documents 相關 scope。
解法:依流程授權;若你在 Workspace 網域下受控,找網域管理員核准必要範圍。
3. 用「檔名」找文件直接失敗
現象:以為有 openByName(),結果呼叫不存在的方法。
解法:先用 DriveApp 依名稱搜尋,拿到 ID 再 openById() 開啟。這是普遍建議的做法。
4. 用在非 Google Docs(像 .docx)導致例外
現象:openById() 成功,但 .getName() 前就報型別不符/不能用 DocumentApp 操作。
原因:DocumentApp 只吃 Google Docs。
解法:先用 DriveApp.getFileById(id).getMimeType() 判斷是不是 application/vnd.google-apps.document;不是的話先轉檔或跳過。
5. 大量迴圈直呼 openById() 效能下滑
現象:大量文件清單逐一開啟,速度緩慢甚至觸發配額限制。
解法:
能不開文件就不開,名稱其實 DriveApp 也能拿(只要你不需要內容)。
需要內容再開;其餘只要名稱就 DriveApp.getFileById(id).getName()。
批次處理時加上 Utilities.sleep() 做節流,或分批執行。
6. 改名後其他系統還沒跟上
現象:剛 setName(),Drive 上或第三方系統顯示還是舊名。
原因:雲端同步需要時間。
作法:
若後續馬上要依檔名做路由,建議以 ID 為準,名稱用來展示即可。官方也鼓勵透過 ID 與 URL 指向正確資源(例如 getUrl())。
進階實戰:把名稱變成流程的「狀態指示器」
範例 7:自動在檔名上加上處理階段標籤
function markDocStage(id, stage) {
const doc = DocumentApp.openById(id);
const base = doc.getName().replace(/\s*\[.*?\]\s*$/, ''); // 去掉舊標籤
doc.setName(`${base} [${stage}]`);
}
用法:markDocStage('ID_xxx', '待審') → 原始名稱 [待審]。流程切換時再呼叫把標籤換掉。
範例 8:把檔名做為郵件主旨、URL 進信件內
function notifyOwner(id, to) {
const doc = DocumentApp.openById(id);
const subject = `文件已更新:${doc.getName()}`;
const body = `請查閱:\n${doc.getUrl()}\n(這封信由系統自動發送)`;
MailApp.sendEmail(to, subject, body);
}
getUrl() 的官方範例就示範把名稱與連結一起寄出,這一招做通知最直觀。
測試與驗收建議
授權先走一遍:
第一次跑任何用到 Document 的腳本,都先在測試帳號授權。
ID 驗證:
從外部來源拿到的 ID,先 DriveApp.getFileById(id) 看看存不存在、型別是否 Google Docs。
名稱一致性:
若你的系統同時用 DriveApp 與 DocumentApp 讀名稱,建議挑一方作為「標準輸出」,避免 UI 同步延遲造成短暫不一致。
批次配額:
大量文件時,避免每筆都 openById();能用 Drive 名稱就用 Drive 名稱,必要時分批執行。
綁定 vs. 獨立:
需要 getActiveDocument() 的腳本請建成 Container-bound Script(在文件中開啟擴充功能 → Apps Script),否則用 ID/URL。
問題集
Q1:getName() 回傳的內容是什麼?
是這份 Google 文件的標題,也就是你在 Docs 介面左上角看到的名稱。
Q2:我能只靠「檔名」找到文件嗎?
DocumentApp 沒有 openByName()。請改用 DriveApp 搜尋檔名,拿到 ID 後再 openById()。
Q3:我想改名,要用哪個方法?
用 Document#setName(newTitle)。官方定義:Sets the document title.。
Q4:要什麼權限(Scopes)?
視操作內容可能需要 documents.currentonly 或 documents。第一次跑會跳授權。
Q5:可以把名稱與連結一起寄信嗎?
可以。getName() 搭 getUrl(),官方示例也這樣做。
