Apps Script用Sheet生成動態網頁(4): 上傳HTML檔案

 昨天完成了如何動態在首頁呈現sheet內的所有網頁,今天製作用來上傳HTML檔案的頁面。這樣就能夠完成維護動態網頁的基礎機制。今天將利用Apps Script提供的google.script.run功能,快速的完成上傳HTML檔案的功能。

延續前幾天的成果,因為上傳檔案需要前後端配合,所以我們需要改script和html的部份。

1. Apps Script的部份(後端/伺服端)

加入兩個函數:uploadHtmlFile()和setContentToSheet()。

function uploadHtmlFile(form) {
let name = form['the-name'];
let file = form['the-file'];
if (!name || !file || file.size <= 0)
throw new Error('名稱或檔案大小有問題');
setContentToSheet(name, file.contents);
return { name, url: getServerUrl() + '?getHtml=' + name };
}

function setContentToSheet(name, content) {
let sheet = SpreadsheetApp.openByUrl(SHEET_URL).getSheets()[0]; // 這裡取第一個Sheet
let name_list = sheet.getRange(1, 1 + COLUMN_IDX_OF_NAME, 1 + sheet.getLastRow(), 1).getValues(); // 取回橫列數個儲存格
let row_idx = name_list.findIndex(r => name === r[COLUMN_IDX_OF_NAME]); // 找出吻合的名稱
if (row_idx < 0) {
sheet.appendRow([name, content]);
} else {
sheet.getRange(1 + row_idx, 1 + COLUMN_IDX_OF_CONTENT).setValue(content); // 設定一個儲存格內容
}
}

setContentToSheet()

首先說明setContentToSheet部份,是使用之前的getContentFromSheet進行調改。如果找不到html名稱,就在sheet加入新的橫列。

sheet.appendRow([name, content]);

找的到html名稱,則直接取代sheet中的HTML內容。

sheet.getRange(1 + row_idx, 1 + COLUMN_IDX_OF_CONTENT).setValue(content);

uploadHtmlFile()

再來說明一下uploadHtmlFile部份,這裡會被使用者端的google.script.run呼叫,並給予表單內容form,它的內容會包含:

  1. html名稱,在form內對應的名稱是the-name
  2. html檔案內容,在form內對應的名稱是the-file

接著我們簡單的檢查一下是否form都有給參數,給了不正常的參數就用丟出例外,以便讓google.script.run部份得知發生錯誤。

if (!name || !file || file.size <= 0)
    throw new Error('名稱或檔案大小有問題');

然後就呼叫setContentToSheet()將html存檔,最後將新上傳的網頁url及網頁名稱傳回給使用者。

2. HTML部份(前端/使用者端)

因為昨天已經完成首頁可從sheet動態增加頁面的功能,所以直接把html放在sheet中了。

上傳檔案呼叫google.script.run的核心程式碼如下:

google.script.run
.withSuccessHandler(onCompleted)
.withFailureHandler(onFailure)
.uploadHtmlFile(event.target);

成功後會呼叫onCompleted,該函數會依照網頁url及網頁名稱產生可以點擊的連結;失敗會呼叫onFailure。

HTML上傳完成的樣子

3. 如何只讓我自己上傳檔案?

AppsScript內建Session可以取的目前登入的使用者,不過要注意使用這功能,是需要重新部屬並同意使用額外的權限的哦!只要在script部份加入下面的validateUploadPermission()做使用者檢查。

function validateUploadPermission() {
let e = Session.getEffectiveUser();
let a = Session.getActiveUser();
if (e?.getEmail() !== a?.getEmail())
throw new Error(`您沒有權限上傳檔案,請確認你已經登入Google帳號`);
}

然後我把它加在uploadHtmlFile的一開始就檢查是否是我自己

function uploadHtmlFile(e) {
validateUploadPermission();
...

這樣在前端部份,如果沒有登入我的帳號就無法上傳。

留言