0. 作品介紹

作者 李信恆 大庄國小

整合校內散落各處的連結與公告事項,並統一管理連結。


25 1 0
非教學
示範影片

1. AI 提示詞

把這段指令貼給 AI,讓它幫你生成程式碼。

我想要建立一個校內連結總表
幫我用Google 試算表建立 【校內連結資料庫】
我希望有些資料我可以直接在試算表更改後,首頁可以直接呈現,並且按下按鈕之後會進到連結網址

需求說明 【
1.請列出人事室、會計室、學務處、教務處、輔導處、總務處、好用教學分享、英文教學專區
2.建立10*8個按鈕,且一列上面要有一個標題
3.每個按鈕可以建立超連結
4.風格要溫暖可愛
】要把它變成程式碼我要發佈
請完整敘述操作步驟 越詳細越好
作業環境
Google試算表
Google Apps Script

請給我後端gs完整程式碼、前端index完整程式碼

2. 資料表規則

請照下面規則建立分頁與欄位。

第1分頁: Links A 欄: 1.分類 B 欄: 2.按鈕名稱 C 欄: 3.連結網址

📄 解析結果(自動表格)

分頁:Links
A 欄 B 欄 C 欄
1.分類 2.按鈕名稱 3.連結網址

3. 開啟 Apps Script

從試算表開 Apps Script,才能直接用 SpreadsheetApp 讀寫資料。

  1. 試算表上方選單:擴充功能 → Apps Script
  2. 刪掉預設的程式碼(或全部選取覆蓋)
  3. 保留/建立檔案:
    • Code.gs
    • index.html

4. 貼上後端(Code.gs)

把後端程式貼到 Apps Script 的 Code.gs。

Code.gs(後端)
// 建立網頁介面
function doGet() {
  return HtmlService.createTemplateFromFile('index')
    .evaluate()
    .setTitle('校內連結總表') // 網頁標題
    .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL) // 允許嵌入
    .addMetaTag('viewport', 'width=device-width, initial-scale=1'); // 手機版適配
}

// 從試算表讀取資料的函式
function getDataFromSheet() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName("Links"); // 讀取名為 Links 的工作表
  
  // 取得所有資料 (假設第一列是標題,從第二列開始抓)
  var data = sheet.getDataRange().getValues();
  
  // 移除第一列標題
  data.shift();
  
  // 整理資料結構
  var output = {};
  
  // 指定分類順序 (依照您的需求排序)
  var order = [
    "人事室", "會計室", "學務處", "教務處", 
    "輔導處", "總務處", "好用教學分享", "英文教學專區"
  ];

  // 初始化物件,確保分類順序正確
  order.forEach(function(category) {
    output[category] = [];
  });

  // 將資料分類
  data.forEach(function(row) {
    var category = row[0]; // A欄: 分類
    var name = row[1];     // B欄: 名稱
    var url = row[2];      // C欄: 連結
    
    // 如果該分類存在於我們的清單中,且名稱跟網址都有值,就加入
    if (output[category] && name && url) {
      output[category].push({
        name: name,
        url: url
      });
    }
  });

  return output;
}
貼到 Apps Script 的 Code.gs 檔案

5. 貼上前端(index.html)

把前端程式貼到 Apps Script 的 index.html。

index.html(前端)
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <link href="https://fonts.googleapis.com/css2?family=Kosugi+Maru&family=Nunito:wght@600&display=swap" rel="stylesheet">
    <style>
      :root {
        /* 定義溫暖配色 */
        --bg-color: #FFFBF0; /* 米黃色背景 */
        --card-bg: #FFFFFF;
        --primary-text: #5D4037; /* 深咖啡色文字 */
        --accent-color: #FF9F89; /* 溫暖珊瑚粉 */
        --hover-color: #FFD166; /* 亮黃色 */
        --shadow: 0 4px 6px rgba(0,0,0,0.05);
      }

      body {
        background-color: var(--bg-color);
        font-family: 'Kosugi Maru', 'Nunito', sans-serif;
        color: var(--primary-text);
        margin: 0;
        padding: 20px;
        display: flex;
        flex-direction: column;
        align-items: center;
      }

      h1 {
        color: #FF8A65;
        text-align: center;
        margin-bottom: 30px;
        font-size: 2.2em;
        text-shadow: 2px 2px 0px #FFF;
      }

      /* 載入中的動畫 */
      #loading {
        text-align: center;
        font-size: 1.2em;
        color: var(--accent-color);
        margin-top: 50px;
      }

      /* 外層容器 */
      .container {
        width: 100%;
        max-width: 1200px;
        display: none; /* 載入完成前隱藏 */
      }

      /* 每一個分類區塊 */
      .section-card {
        background: var(--card-bg);
        border-radius: 20px;
        padding: 20px 30px;
        margin-bottom: 25px;
        box-shadow: 0 8px 15px rgba(255, 159, 137, 0.15); /* 粉色系陰影 */
        border: 2px solid #FFF0E6;
        transition: transform 0.2s;
      }

      .section-card:hover {
        transform: translateY(-3px);
      }

      /* 分類標題 */
      .section-title {
        font-size: 1.5em;
        color: var(--accent-color);
        margin-bottom: 15px;
        border-bottom: 2px dashed #FFCCBC;
        padding-bottom: 8px;
        display: inline-block;
      }

      /* 按鈕網格系統 - 為了符合寬螢幕 10 個按鈕的需求,使用 Grid */
      .button-grid {
        display: grid;
        /* 自動填滿,最小寬度 100px,最大 1fr。螢幕夠寬會顯示多個,最多可以排到 10 個 */
        grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
        gap: 15px;
      }

      /* 按鈕樣式 */
      .link-btn {
        background-color: #FFF;
        border: 2px solid #FFCCBC;
        color: var(--primary-text);
        padding: 10px 5px;
        border-radius: 12px;
        text-decoration: none;
        text-align: center;
        font-size: 0.95em;
        font-weight: bold;
        transition: all 0.3s ease;
        display: flex; /* 讓文字垂直置中 */
        align-items: center;
        justify-content: center;
        min-height: 40px;
        box-shadow: 0 2px 5px rgba(0,0,0,0.05);
        word-break: break-all; /* 防止文字爆開 */
      }

      .link-btn:hover {
        background-color: var(--hover-color);
        color: #fff;
        border-color: var(--hover-color);
        transform: scale(1.05) rotate(-1deg); /* 可愛的小動態 */
        box-shadow: 0 4px 8px rgba(255, 209, 102, 0.4);
        cursor: pointer;
      }

      /* 為不同分類加一點點不同的邊框顏色變化 (選用) */
      .section-card:nth-child(odd) .link-btn { border-color: #B2DFDB; }
      .section-card:nth-child(even) .link-btn { border-color: #FFCCBC; }
      
      .section-card:nth-child(odd) .link-btn:hover { background-color: #4DB6AC; border-color: #4DB6AC; }
      .section-card:nth-child(even) .link-btn:hover { background-color: #FF8A65; border-color: #FF8A65; }

    </style>
  </head>
  <body>

    <h1>🏫 校內連結小幫手</h1>
    
    <div id="loading">
      正在整理連結中,請稍候... ☁️
    </div>

    <div id="container" class="container">
      </div>

    <script>
      // 當網頁載入時執行
      window.onload = function() {
        google.script.run
          .withSuccessHandler(renderPage)
          .getDataFromSheet();
      };

      // 接收後端資料並產生畫面
      function renderPage(data) {
        var container = document.getElementById('container');
        var loading = document.getElementById('loading');
        
        // 隱藏讀取中,顯示內容
        loading.style.display = 'none';
        container.style.display = 'block';

        // 遍歷所有分類
        for (var category in data) {
          var links = data[category];
          
          // 如果該分類沒有連結,可以選擇不顯示,這裡我設定都顯示框架方便您看
          // if (links.length === 0) continue; 

          // 1. 建立分類卡片
          var sectionCard = document.createElement('div');
          sectionCard.className = 'section-card';

          // 2. 建立標題
          var title = document.createElement('div');
          title.className = 'section-title';
          title.textContent = category; // 例如:人事室
          sectionCard.appendChild(title);

          // 3. 建立按鈕網格容器
          var grid = document.createElement('div');
          grid.className = 'button-grid';

          // 4. 建立該分類下的所有按鈕
          // 如果需要固定顯示10個格子(即使沒資料),可以用for迴圈跑10次
          // 這裡依照您的需求:有資料才顯示,但CSS支援一排最多約10個
          
          links.forEach(function(link) {
            var a = document.createElement('a');
            a.className = 'link-btn';
            a.href = link.url;
            a.textContent = link.name;
            a.target = "_blank"; // 在新視窗開啟
            grid.appendChild(a);
          });

          // 如果該分類完全沒資料,顯示一個提示
          if (links.length === 0) {
            var emptyMsg = document.createElement('div');
            emptyMsg.style.color = '#ccc';
            emptyMsg.style.fontSize = '0.9em';
            emptyMsg.textContent = '(尚無連結)';
            grid.appendChild(emptyMsg);
          }

          sectionCard.appendChild(grid);
          container.appendChild(sectionCard);
        }
      }
    </script>
  </body>
</html>
貼到 Apps Script 的 index.html 檔案

6. 部署

部署成 Web App 後,就會拿到可分享網址。

  1. Apps Script 右上:部署 → 新部署
  2. 類型選:Web app
  3. 執行身分:你
  4. 存取權限:任何人
  5. 完成後複製網址

💬 評論區

老師們的交流與提問

載入評論中...