1. 簡介
本程式碼研究室的目標是協助您瞭解如何編寫 Cloud 函式,以回應上傳至 Cloud Storage 的 CSV 檔案、讀取當中的內容,並使用 Sheets API 更新 Google 試算表。
如果是由其他程序手動「以 CSV 匯入」採用這可確保在資料可用時,就能立即分析試算表中的資料 (可能由其他團隊製作)。
實作方式如下:
2. 設定和需求
自修環境設定
提醒您,專案 ID 是所有 Google Cloud 專案的專屬名稱 (已經有人使用上述名稱,很抱歉對您不符!)。稍後在本程式碼研究室中會稱為 PROJECT_ID
。
- 接下來,您需要在 Cloud 控制台中啟用計費功能,才能使用 Google Cloud 資源。
執行這個程式碼研究室並不會產生任何費用,如果有的話。請務必依照「清除所用資源」一節指示本節將說明如何關閉資源,這樣您就不會產生本教學課程結束後產生的費用。Google Cloud 的新使用者符合 $300 美元免費試用計畫的資格。
3. 建立並設定 Google 試算表,並啟用 API
首先,請建立新的 Google 試算表文件 (這份工作表適用於所有使用者)。建立完成後,請記住 ID;該變數會做為我們編寫的函式的環境變數:
在 GCP 控制台中前往「API 和服務」,為新建立的專案啟用 Google Sheets API其次是「API 程式庫」區段:
在「IAM 與管理員」前往「服務帳戶」專區並記下 App Engine 預設服務帳戶的電子郵件。格式應為 your-project-id@appspot.gserviceaccount.com
。當然,您也可以建立自己的服務帳戶來執行這項動作。
最後,只要使用 [共用] 選單,將編輯權限授予此服務帳戶即可按鈕:
完成這項設定後,我們就能編寫 Cloud 函式,並將其設為使用這個服務帳戶。它可以寫入我們剛建立的這份試算表文件。
4. 建立儲存空間值區
讓我們建立 Cloud 函式來監控新 CSV 檔案的值區。
在控制台中,透過左側選單前往「儲存空間」...:
... 然後建立名為 csv2sheet-POSTFIX
的新值區 (將 POSTFIX 替換為不重複的項目),並將其他所有設定均設為預設值:
5. 建立 Cloud 函式
我們現在可以建立名為 csv2sheet
的 Cloud 函式,這個函式會在檔案上傳至特定 Cloud Storage 值區時觸發。程式碼將以 Node.js 8 編寫,並直接透過 Cloud 控制台的內嵌編輯器,以非同步函式編寫。
請務必將觸發條件設為「Cloud Storage」並將值區名稱調整為您在上一個步驟中建立的值區名稱。
同時更新要寫入 csv2sheet
的函式進入點:
現在,將函式主體變更為 :
- 使用 Cloud Storage 和 Sheets API
- 將
csv2sheet
函式標示為async
- 從 Cloud Storage 事件中繼資料取得
fileName
的訴訟保留,並取得要建立的新工作表名稱:
const {google} = require("googleapis");
const {Storage} = require("@google-cloud/storage")
exports.csv2sheet = async (data, context) => {
var fileName = data.name;
// basic check that this is a *.csv file, etc...
if (!fileName.endsWith(".csv")) {
console.log("Not a .csv file, ignoring.");
return;
}
// define name of new sheet
const sheetName = fileName.slice(0, -4);
// TODO!
};
此為在稍後的說明,您必須在此處使用 async
才能使用 await
。
建立這個函式時,有幾個重要選項包括 (按一下畫面底部的「更多」連結):
- 使用下拉式選單選取上述的服務帳戶
- 定義名為
SPREADSHEET_ID
的環境變數,這個變數應與您先前建立的工作表文件相符:
最後的設定步驟如下:package.json
內容包含 Cloud Storage 和 Google 試算表 API,做為我們將使用的兩個依附元件 (使用控制台的內嵌編輯器「PACKAGE.JSON」分頁):
{
"name": "csv2sheet",
"version": "0.0.42",
"dependencies": {
"googleapis": "^51.0.0",
"@google-cloud/storage": "^5.0.1"
}
}
按照說明完成設定後,請點選「建立」!幾分鐘後,系統就能建立及部署函式。
6. 設定 Auth API 和 Sheets API
在使用內嵌編輯器編寫任何進一步程式碼之前,我們必須在建立具備適當儲存空間和試算表範圍的 Google Client API 時進行封鎖 (提醒您,這是 async
函式的一部分)。
在控制台的函式編輯器中按一下「編輯」並將下列程式碼加入 csv2sheet
函式的主體:
// block on auth + getting the sheets API object
const auth = await google.auth.getClient({
scopes: [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/devstorage.read_only"
]
});
接著,我們可以建立 Sheets API 用戶端:
const sheetsAPI = google.sheets({version: 'v4', auth});
7. 使用 Sheets API 建立空白工作表
透過 Sheets API 用戶端,我們可以在文件中建立簡單的新工作表,但在此之前,在此先簡單說明一下詞彙:
- 試算表指的是實際文件,由文件 ID 參照 (如前文所述,可在文件網址中查看)
- 工作表是文件中的其中一個分頁標籤,可以用名稱 (分頁名稱) 或在工作表建立時產生的 ID 參照。
請注意,以下函式會透過 Sheets API 用戶端,在位置 2 (通常是在預設「Sheet1」之後) 建立空白工作表,其中有 26 個資料欄、2000 列,第一列會凍結 (使用內嵌編輯器將其新增至函式):
function addEmptySheet(sheetsAPI, sheetName) {
return new Promise((resolve, reject) => {
const emptySheetParams = {
spreadsheetId: process.env.SPREADSHEET_ID,
resource: {
requests: [
{
addSheet: {
properties: {
title: sheetName,
index: 1,
gridProperties: {
rowCount: 2000,
columnCount: 26,
frozenRowCount: 1
}
}
}
}
]
}
};
sheetsAPI.spreadsheets.batchUpdate( emptySheetParams, function(err, response) {
if (err) {
reject("The Sheets API returned an error: " + err);
} else {
const sheetId = response.data.replies[0].addSheet.properties.sheetId;
console.log("Created empty sheet: " + sheetId);
resolve(sheetId);
}
}
);
});
}
請注意,我們該如何使用先前建立的 SPREADSHEET_ID
環境變數,而非以硬式編碼的方式寫入試算表參照。
我們必須記住 sheetId
,才能針對這份工作表再次提出要求。此外,工作表名稱不得重複,如果已有名為 sheetName
的工作表,建立作業就會失敗。
Sheets API 中的 batchUpdate
函式是與文件互動的常見方式,詳情請參閱這裡。
8. 讀取 CSV 檔案中的資料
現在我們已能轉儲資料,讓我們在內嵌編輯器中進一步開發 Cloud 函式,並使用 Cloud Storage API 從剛上傳的檔案中擷取實際資料,然後儲存在字串中:
function readCSVContent(sheetsAPI, file, sheetName) {
return new Promise((resolve, reject) => {
const storage = new Storage();
let fileContents = new Buffer('');
storage.bucket(file.bucket).file(file.name).createReadStream()
.on('error', function(err) {
reject('The Storage API returned an error: ' + err);
})
.on('data', function(chunk) {
fileContents = Buffer.concat([fileContents, chunk]);
})
.on('end', function() {
let content = fileContents.toString('utf8');
console.log("CSV content read as string : " + content );
resolve(content);
});
});
}
9. 在新建立的工作表中填入資料
現在,讓我們使用相同的工作表用戶端 API 和我們剛收集到的資料,為我們建立的工作表填入資料。我們也會趁這個機會在工作表資料欄中新增一些樣式 (變更上列的字型大小,並使標題變成粗體):
function populateAndStyle(sheetsAPI, theData, sheetId) {
return new Promise((resolve, reject) => {
// Using 'batchUpdate' allows for multiple 'requests' to be sent in a single batch.
// Populate the sheet referenced by its ID with the data received (a CSV string)
// Style: set first row font size to 11 and to Bold. Exercise left for the reader: resize columns
const dataAndStyle = {
spreadsheetId: process.env.SPREADSHEET_ID,
resource: {
requests: [
{
pasteData: {
coordinate: {
sheetId: sheetId,
rowIndex: 0,
columnIndex: 0
},
data: theData,
delimiter: ","
}
},
{
repeatCell: {
range: {
sheetId: sheetId,
startRowIndex: 0,
endRowIndex: 1
},
cell: {
userEnteredFormat: {
textFormat: {
fontSize: 11,
bold: true
}
}
},
fields: "userEnteredFormat(textFormat)"
}
}
]
}
};
sheetsAPI.spreadsheets.batchUpdate(dataAndStyle, function(err, response) {
if (err) {
reject("The Sheets API returned an error: " + err);
} else {
console.log(sheetId + " sheet populated with " + theData.length + " rows and column style set.");
resolve();
}
});
});
}
這段程式碼應新增至 Cloud 函式中,目前作業已完成 99%!
請注意,資料和樣式會如何以多個 requests
合併為單一 Sheets API batchUpdate
呼叫。如此一來,更新更有效率,整體作業就能更有效率。
另請注意,我們定義的編輯範圍必須符合先前建立的工作表大小。也就是說,如果內容超過 26 欄 (建立工作表時使用 columnCount
值),就會因這組程式碼失敗。
如果一切順利,您現在可以:
- 儲存更新後的函式
- 將 CSV 檔案拖曳到值區中
- 試算表中就會顯示相對應的資料!
10. 全部整合並測試流程
您剛剛所討論函式的呼叫可以在原始 csv2sheet
函式中作為連續的封鎖呼叫進行:
const sheetId = await addEmptySheet(sheetsAPI, sheetName);
const theData = await readCSVContent(sheetsAPI, data, sheetName);
await populateAndStyle(sheetsAPI, theData, sheetId);
如果您需要完整的函式原始碼,可以在這裡取得 (從單一集裡取得全部程式碼可能比較簡單)。
完成所有設定後,只要將 CSV 檔案上傳至正確的值區,系統就會更新至含有檔案內容的新工作表。如果您沒有 CSV 檔案範例,可使用以下的範例 CSV 檔案。
請嘗試將多個檔案上傳至值區,看看會發生什麼事!
11. 大功告成!是時候淘汰基礎架構了
開玩笑,沒有需要拆除的基礎架構,這一切都是在無伺服器的情況下完成!
您可以視需要刪除 Cloud 函式和您建立的值區,甚至是整個專案。
12. 接下來要做什麼?
本程式碼研究室將逐步引導您聆聽相關步驟,以監聽 Cloud 函式中上傳至 Cloud Storage 值區的作業,以使用適當的 API 更新 Google 試算表。
以下是一些後續的步驟:
- 查看 Cloud Functions 使用指南 (包含一些最佳做法)
- 逐步進行其中一個 Cloud Functions 教學課程。
- 進一步探索 Google Sheets API
如果您在使用本程式碼研究室時遇到任何問題,歡迎點選左下角的連結,回報任何問題。
感謝你提供寶貴意見!