事實測試:9.11 和 9.9 誰比較大?
開啟你常用的 AI(Gemini、ChatGPT 都可以),開一個新對話。
複製下方問題貼上,看看 AI 怎麼回答。
回到這裡,按下你的 AI 給出的答案。
9.11 和 9.9 誰比較大?
請輸入「部門-名字」與通關密語進入課程指引。
提示:集團的英文名,不分大小寫。
溝通力 × 創作力 × 效率力。這份指引整理本堂課的實作任務與可直接複製的提示詞:問不到重點練溝通、想法做不出練創作、重複一直做練效率。點上方分頁開始,每個任務做完直接送出答案。
這堂課不是逐一展示 AI 功能,而是建立正確的使用直覺:AI 怎麼運作、哪裡會出錯、怎麼問才問得好,以及怎麼把重複的事封裝起來。講義為課堂重點摘要,以課堂簡報為準。
問 AI「9.11 和 9.9 誰比較大」它可能答錯,請它想五句維護公告開頭它句句有梗——同一個 AI,兩種用法。要事實,就要查證;要靈感,就大膽要。搞混這兩件事,是多數人踩坑的起點。
AI 不是計算機,也不是搜尋引擎。它根據上下文一個字一個字推測「接下來最合理的內容」。理解這件事,你就同時理解了它的強項與弱點:很會整理、改寫、延伸;但也可能一本正經地說錯話——這就是幻覺,不是故障,是天性。
掃描版 PDF、圖片裡的文字、格式複雜的表格,AI 可能讀不全或讀錯。丟資料前先想一下:它拿到的是「文字」還是「圖」?整理成純文字或 Markdown 最穩。
一個對話累積的上下文會互相干擾。換任務就開新對話,讓 AI 專心——這也是今天每個任務都請你「開新的對話視窗」的原因。
先親身體驗 AI 的兩種天性——會一本正經地答錯、也會給你意想不到的靈感;再用 RODES 法則,把模糊的需求變成 AI 一次到位的精準提問。
開啟你常用的 AI(Gemini、ChatGPT 都可以),開一個新對話。
複製下方問題貼上,看看 AI 怎麼回答。
回到這裡,按下你的 AI 給出的答案。
9.11 和 9.9 誰比較大?
開一個新對話,複製下方提示詞貼上。
從 AI 給你的 5 句裡,挑一句你最喜歡的。
貼到下方輸入框送出——每個人的答案都不一樣,這就是靈感模式。
幫我想 5 句讓玩家心甘情願看完系統維護公告的開頭句,要有趣,不要官腔。
想一個你部門本週真實會遇到的任務,照下面四步,把「隨口一句的需求」升級成「AI 一次到位的提問」。
先用大白話寫下你的需求——寫得遜沒關係,這就是原料(例:「幫我回一封客訴信」)。
開啟下方「RODES 提示詞優化器」,把你的遜版需求貼進去,拿到優化後的提示詞。
開一個新的對話視窗,貼上優化後的提示詞執行;不滿意就繼續調整。
把「優化後的提示詞」和「滿意的產出」貼回下方送出。
剛剛老師用 RODES 拿到的電玩展提案架構,現在輪到你——把它變成一份拿得出手的簡報。
情境:你是橘子集團的員工,《新楓之谷》要參加明年的台北國際電玩展,提案方向已經確定——預算 300 萬內、主打年底新改版、帶到經典版吸引回鍋老玩家。現在要做出對內部主管提案的簡報。
開一個新的對話視窗(Gemini)。
複製下方提示詞貼上,等 Gemini 產出簡報內容並做成 Google 簡報。
開啟簡報,點右上角「共用」→ 改成「知道連結的使用者皆可檢視」→ 複製連結。
把簡報連結貼回下方送出。
請扮演資深遊戲展場策展人。我是橘子集團的員工,《新楓之谷》要參加明年的台北國際電玩展,我需要對內部主管提案攤位規劃。 提案條件: - 預算上限 300 萬元 - 主打年底新改版內容,並帶到《新楓之谷:經典版》吸引回鍋的老玩家 請幫我製作一份 6 頁的提案簡報,頁面依序為:封面、展場核心主題與提案摘要、空間動線規劃、舞台與玩家互動活動(含經典版回鍋玩家專區)、預算分配、預期效益(KPI)。每頁有標題與 3 點以內的重點。若資訊不足,請以合理假設完成,並把假設清單放在最後一頁下方補充說明,不需反問我。 完成後,請直接把這份內容做成 Google 簡報。
開啟你的簡報(自己做的或講師範本副本都可以),到首頁。
點開右上角 Gemini 側邊欄,請它把首頁圖片改成更簡潔的風格,換上滿意的那張。
完成後回來登記完成。
在簡報的 Gemini 側邊欄,複製下方提示詞貼上。
確認新頁面有加進來、風格跟前面一致。
完成後回來登記完成。
請幫我在簡報中新增第八頁,主題為「O2O 數位互動與數據成效追蹤」。請列出 3 點重點,說明如何利用手機互動網頁設計虛擬獎勵與排行榜機制來串聯攤位動線、如何精準收集回鍋玩家與新玩家的數據名單,以及展後如何運用這些資料進行媒體廣告再行銷。請維持與前述簡報一致的提案風格與排版。
下載下方「大師姐」的 IP 圖片。
開一個新的對話視窗,上傳範例圖,貼上提示詞 ①,讓 Gemini 分析出風格描述。
接著上傳自己的照片(或任何一張人像照),貼上提示詞 ②,依剛剛的風格生成新圖。
把生成的圖片下載下來,回到這裡上傳。
提示詞 ①(分析風格):
請分析這張圖片的視覺風格,包括:材質與質感、光線、色調配色、人物頭身比例與五官特徵、整體氛圍。整理成一段之後可以直接用來生成同風格圖片的「風格描述」。
提示詞 ②(上傳人像照後生成):
這是一張人像照片,請依照剛剛整理的風格描述,把照片中的人物重新生成為同樣風格的 3D 角色圖,保留人物的髮型、服裝特色與姿勢。
兩條路線:先在 Google 文件裡讓 Gemini 幫你讀寫改,再用 Gemini Notebook 把多份文件變成可追問的知識庫。
點「使用範本」,把文件建立到自己的雲端硬碟。
打開右側 Gemini 側邊欄,輸入下方提示詞,把第三條「部門與職掌」的表格變成條列,然後點「插入」取代,即完成。
請把文件中第三條「部門與職掌」的表格改寫成條列式清單:每個部門一個標題,底下條列該部門的職掌重點,方便新人快速閱讀。
開啟範本(或下載 CSV 上傳到自己的 Google 試算表)。
點開右上角 Gemini 側邊欄,依序試下面三張卡。
做完回來登記完成。
請檢查這張報名表的資料品質問題:重複報名(同一 Email 報了兩次以上)、Email 缺漏或格式錯誤、日期格式不一致,條列告訴我哪幾列需要處理。
請新增一欄「活動分類」,把「想參加的活動」歸類成:舞台活動/新作試玩/經典版懷舊區/未明確;再新增一欄「玩家類型」,依「是否玩過橘子的遊戲」分成老玩家/新玩家。最後統計各活動分類的人數與老玩家比例。
請用 150 字寫一段給主管的報名狀況摘要:目前有效報名人數(扣掉重複)、最熱門的活動、資料需要補齊的地方,以及建議下一步。
一鍵清洗髒資料、自建多平台 CSV 上傳中心、再到自動寄信匯報,把每天重複的報表苦工變成一條自動化產線。
延伸挑戰:修改模板,以既有腳本參考,將【拆分多個電子郵件】轉換為直向呈現
const DATA_START_ROW = 2;
const TARGET_COLUMNS = 5;
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('資料匯整工具')
.addItem('上傳 CSV', 'showUploadDialog')
.addItem('清空資料', 'clearImportedData')
.addToUi();
}
function showUploadDialog() {
const html = HtmlService.createHtmlOutputFromFile('UploadDialog')
.setWidth(520)
.setHeight(360);
SpreadsheetApp.getUi().showModalDialog(html, '上傳 CSV 檔');
}
function clearImportedData() {
clearImportedData_();
SpreadsheetApp.getUi().alert('已清空資料。');
}
function importCsvFiles(files) {
if (!files || files.length === 0) {
throw new Error('請至少上傳一份 CSV 檔。');
}
const sheet = getTargetSheet_();
clearImportedData_();
const allRows = [];
files.forEach(function (file) {
const fileName = file.name || '';
const csvText = file.content || '';
const sourcePlatform = detectSourcePlatform_(fileName, csvText);
const rows = parseCsv_(csvText);
if (rows.length < 2) return;
const headers = rows[0].map(normalizeHeader_);
const dataRows = rows.slice(1);
dataRows.forEach(function (row) {
if (isEmptyRow_(row)) return;
allRows.push(mapRowToTarget_(sourcePlatform, headers, row));
});
});
if (allRows.length === 0) {
throw new Error('沒有讀到可匯入的資料,請確認 CSV 內容。');
}
sheet.getRange(DATA_START_ROW, 1, allRows.length, TARGET_COLUMNS).setValues(allRows);
return `匯入完成,共 ${allRows.length} 筆資料。`;
}
function getTargetSheet_() {
return SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
}
function clearImportedData_() {
const sheet = getTargetSheet_();
const lastRow = sheet.getLastRow();
if (lastRow < DATA_START_ROW) return;
sheet
.getRange(DATA_START_ROW, 1, lastRow - DATA_START_ROW + 1, TARGET_COLUMNS)
.clearContent();
}
function detectSourcePlatform_(fileName, csvText) {
const lowerName = fileName.toLowerCase();
const firstLine = csvText.split(/\r?\n/)[0] || '';
if (
lowerName.includes('google') ||
lowerName.includes('form') ||
firstLine.includes('電子郵件地址')
) {
return 'Google Form';
}
if (
lowerName.includes('accupass') ||
firstLine.includes('票券編號')
) {
return 'Accupass';
}
if (
lowerName.includes('vendor') ||
lowerName.includes('廠商') ||
lowerName.includes('system') ||
firstLine.includes('廠商流水號')
) {
return '廠商自有系統';
}
return '未知來源';
}
function mapRowToTarget_(sourcePlatform, headers, row) {
if (sourcePlatform === 'Google Form') {
return [
sourcePlatform,
getCellByHeader_(headers, row, '回覆編號'),
getCellByHeader_(headers, row, '姓名'),
getCellByHeader_(headers, row, '服務單位'),
getCellByHeader_(headers, row, '電子郵件地址')
];
}
if (sourcePlatform === 'Accupass') {
return [
sourcePlatform,
getCellByHeader_(headers, row, '票券編號'),
getCellByHeader_(headers, row, '參加人姓名'),
getCellByHeader_(headers, row, '公司名稱'),
getCellByHeader_(headers, row, '參加人Email')
];
}
if (sourcePlatform === '廠商自有系統') {
return [
sourcePlatform,
getCellByHeader_(headers, row, '廠商流水號'),
getCellByHeader_(headers, row, '聯絡人'),
getCellByHeader_(headers, row, '單位名稱'),
getCellByHeader_(headers, row, '聯絡信箱')
];
}
return [sourcePlatform, '', '', '', ''];
}
function getCellByHeader_(headers, row, headerName) {
const index = headers.indexOf(normalizeHeader_(headerName));
if (index === -1) return '';
return row[index] || '';
}
function normalizeHeader_(header) {
return String(header || '')
.trim()
.replace(/\s+/g, '')
.toLowerCase();
}
function isEmptyRow_(row) {
return row.every(function (cell) {
return String(cell || '').trim() === '';
});
}
function parseCsv_(text) {
const rows = [];
let row = [];
let cell = '';
let inQuotes = false;
for (let i = 0; i < text.length; i++) {
const char = text[i];
const nextChar = text[i + 1];
if (char === '"' && inQuotes && nextChar === '"') {
cell += '"';
i++;
continue;
}
if (char === '"') {
inQuotes = !inQuotes;
continue;
}
if (char === ',' && !inQuotes) {
row.push(cell);
cell = '';
continue;
}
if ((char === '\n' || char === '\r') && !inQuotes) {
if (char === '\r' && nextChar === '\n') i++;
row.push(cell);
rows.push(row);
row = [];
cell = '';
continue;
}
cell += char;
}
if (cell !== '' || row.length > 0) {
row.push(cell);
rows.push(row);
}
return rows;
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
body {
font-family: Arial, "Noto Sans TC", sans-serif;
padding: 20px;
color: #222;
}
h2 {
margin: 0 0 12px;
font-size: 20px;
}
p {
margin: 0 0 16px;
line-height: 1.6;
color: #555;
}
.box {
border: 1px solid #ddd;
border-radius: 8px;
padding: 16px;
background: #fafafa;
}
input {
width: 100%;
margin: 8px 0 16px;
}
button {
border: none;
border-radius: 6px;
padding: 10px 16px;
cursor: pointer;
font-size: 14px;
}
.primary {
background: #5b21b6;
color: white;
}
.secondary {
background: #e5e7eb;
color: #111;
margin-left: 8px;
}
#status {
margin-top: 16px;
color: #444;
line-height: 1.5;
}
</style>
</head>
<body>
<h2>上傳 CSV 檔</h2>
<p>請選擇三份 CSV 檔,系統會整理成:來源平台、報名編號、姓名、單位、Email。</p>
<div class="box">
<input id="csvFiles" type="file" accept=".csv,text/csv" multiple>
<button class="primary" onclick="uploadFiles()">開始匯入</button>
<button class="secondary" onclick="google.script.host.close()">取消</button>
<div id="status"></div>
</div>
<script>
function uploadFiles() {
const input = document.getElementById('csvFiles');
const status = document.getElementById('status');
const files = Array.from(input.files || []);
if (files.length === 0) {
status.textContent = '請先選擇 CSV 檔。';
return;
}
status.textContent = '讀取檔案中...';
Promise.all(files.map(readFileAsText))
.then(function (filePayloads) {
status.textContent = '匯入中,請稍候...';
google.script.run
.withSuccessHandler(function (message) {
status.textContent = message;
})
.withFailureHandler(function (error) {
status.textContent = '匯入失敗:' + error.message;
})
.importCsvFiles(filePayloads);
})
.catch(function (error) {
status.textContent = '讀取檔案失敗:' + error.message;
});
}
function readFileAsText(file) {
return new Promise(function (resolve, reject) {
const reader = new FileReader();
reader.onload = function (event) {
resolve({
name: file.name,
content: event.target.result
});
};
reader.onerror = function () {
reject(new Error(file.name + ' 讀取失敗'));
};
reader.readAsText(file, 'UTF-8');
});
}
</script>
</body>
</html>
const DATA_START_ROW = 2;
const TARGET_COLUMNS = 5;
const MAIL_NAME_COLUMN = 3;
const MAIL_EMAIL_COLUMN = 5;
const MAIL_STATUS_COLUMN = 6;
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('資料匯整工具')
.addItem('上傳 CSV', 'showUploadDialog')
.addItem('清空資料', 'clearImportedData')
.addSeparator()
.addItem('寄送通知信', 'sendNotificationEmails')
.addItem('寄送信件', '寄送信件')
.addToUi();
}
function showUploadDialog() {
const html = HtmlService.createHtmlOutputFromFile('UploadDialog')
.setWidth(520)
.setHeight(360);
SpreadsheetApp.getUi().showModalDialog(html, '上傳 CSV 檔');
}
function clearImportedData() {
clearImportedData_();
SpreadsheetApp.getUi().alert('已清空資料。');
}
function importCsvFiles(files) {
if (!files || files.length === 0) {
throw new Error('請至少上傳一份 CSV 檔。');
}
const sheet = getTargetSheet_();
clearImportedData_();
const allRows = [];
files.forEach(function (file) {
const fileName = file.name || '';
const csvText = file.content || '';
const sourcePlatform = detectSourcePlatform_(fileName, csvText);
const rows = parseCsv_(csvText);
if (rows.length < 2) return;
const headers = rows[0].map(normalizeHeader_);
const dataRows = rows.slice(1);
dataRows.forEach(function (row) {
if (isEmptyRow_(row)) return;
allRows.push(mapRowToTarget_(sourcePlatform, headers, row));
});
});
if (allRows.length === 0) {
throw new Error('沒有讀到可匯入的資料,請確認 CSV 內容。');
}
sheet.getRange(DATA_START_ROW, 1, allRows.length, TARGET_COLUMNS).setValues(allRows);
return `匯入完成,共 ${allRows.length} 筆資料。`;
}
function getTargetSheet_() {
return SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
}
function clearImportedData_() {
const sheet = getTargetSheet_();
const lastRow = sheet.getLastRow();
if (lastRow < DATA_START_ROW) return;
sheet
.getRange(DATA_START_ROW, 1, lastRow - DATA_START_ROW + 1, TARGET_COLUMNS)
.clearContent();
}
function detectSourcePlatform_(fileName, csvText) {
const lowerName = fileName.toLowerCase();
const firstLine = csvText.split(/\r?\n/)[0] || '';
if (
lowerName.includes('google') ||
lowerName.includes('form') ||
firstLine.includes('電子郵件地址')
) {
return 'Google Form';
}
if (lowerName.includes('accupass') || firstLine.includes('票券編號')) {
return 'Accupass';
}
if (
lowerName.includes('vendor') ||
lowerName.includes('廠商') ||
lowerName.includes('system') ||
firstLine.includes('廠商流水號')
) {
return '廠商自有系統';
}
return '未知來源';
}
function mapRowToTarget_(sourcePlatform, headers, row) {
if (sourcePlatform === 'Google Form') {
return [
sourcePlatform,
getCellByHeader_(headers, row, '回覆編號'),
getCellByHeader_(headers, row, '姓名'),
getCellByHeader_(headers, row, '服務單位'),
getCellByHeader_(headers, row, '電子郵件地址')
];
}
if (sourcePlatform === 'Accupass') {
return [
sourcePlatform,
getCellByHeader_(headers, row, '票券編號'),
getCellByHeader_(headers, row, '參加人姓名'),
getCellByHeader_(headers, row, '公司名稱'),
getCellByHeader_(headers, row, '參加人Email')
];
}
if (sourcePlatform === '廠商自有系統') {
return [
sourcePlatform,
getCellByHeader_(headers, row, '廠商流水號'),
getCellByHeader_(headers, row, '聯絡人'),
getCellByHeader_(headers, row, '單位名稱'),
getCellByHeader_(headers, row, '聯絡信箱')
];
}
return [sourcePlatform, '', '', '', ''];
}
function getCellByHeader_(headers, row, headerName) {
const index = headers.indexOf(normalizeHeader_(headerName));
if (index === -1) return '';
return row[index] || '';
}
function normalizeHeader_(header) {
return String(header || '')
.trim()
.replace(/\s+/g, '')
.toLowerCase();
}
function isEmptyRow_(row) {
return row.every(function (cell) {
return String(cell || '').trim() === '';
});
}
function parseCsv_(text) {
const rows = [];
let row = [];
let cell = '';
let inQuotes = false;
for (let i = 0; i < text.length; i++) {
const char = text[i];
const nextChar = text[i + 1];
if (char === '"' && inQuotes && nextChar === '"') {
cell += '"';
i++;
continue;
}
if (char === '"') {
inQuotes = !inQuotes;
continue;
}
if (char === ',' && !inQuotes) {
row.push(cell);
cell = '';
continue;
}
if ((char === '\n' || char === '\r') && !inQuotes) {
if (char === '\r' && nextChar === '\n') i++;
row.push(cell);
rows.push(row);
row = [];
cell = '';
continue;
}
cell += char;
}
if (cell !== '' || row.length > 0) {
row.push(cell);
rows.push(row);
}
return rows;
}
function sendNotificationEmails() {
const ui = SpreadsheetApp.getUi();
const sheet = getTargetSheet_();
const lastRow = sheet.getLastRow();
if (lastRow < DATA_START_ROW) {
ui.alert('目前沒有可寄送的資料。');
return;
}
const rowCount = lastRow - DATA_START_ROW + 1;
const values = sheet
.getRange(DATA_START_ROW, 1, rowCount, TARGET_COLUMNS)
.getValues();
let sentCount = 0;
let skippedCount = 0;
for (let i = 0; i < values.length; i++) {
const rowNumber = DATA_START_ROW + i;
const name = values[i][MAIL_NAME_COLUMN - 1];
const email = values[i][MAIL_EMAIL_COLUMN - 1];
const status = values[i][MAIL_STATUS_COLUMN - 1];
if (status && String(status).trim() !== '') {
skippedCount++;
continue;
}
if (!email || String(email).trim() === '') {
skippedCount++;
continue;
}
const subject = '【報名確認】我們已收到你的報名';
const body =
(name ? name : '您好') + ',\n\n' +
'我們已經收到你的報名資料,活動相關細節將另行通知。\n\n' +
'謝謝你的參與!';
try {
MailApp.sendEmail({
to: String(email).trim(),
subject: subject,
body: body
});
sheet.getRange(rowNumber, MAIL_STATUS_COLUMN).setValue('已寄送');
sentCount++;
} catch (err) {
sheet.getRange(rowNumber, MAIL_STATUS_COLUMN).setValue('寄送失敗:' + err.message);
}
}
ui.alert('寄送完成:成功 ' + sentCount + ' 筆,略過 ' + skippedCount + ' 筆。');
}
function 寄送信件() {
const sheet = SpreadsheetApp.getActiveSheet();
const lastRow = sheet.getLastRow();
// 沒有資料列(只有標題)就提醒並結束
if (lastRow < 2) {
SpreadsheetApp.getUi().alert('沒有可寄送的資料。');
return;
}
// 從第 2 列開始(跳過標題),讀取 B、C、D 三欄
// B=2, C=3, D=4,共 3 欄
const data = sheet.getRange(2, 2, lastRow - 1, 3).getValues();
let 成功 = 0;
let 略過 = 0;
const 錯誤清單 = [];
data.forEach((row, i) => {
const 列號 = i + 2; // 對應實際試算表列號
const 收件人 = String(row[0]).trim(); // B 欄
const 主旨 = String(row[1]).trim(); // C 欄
const 內容 = String(row[2]); // D 欄
// B 欄沒填 email 就略過
if (!收件人) {
略過++;
return;
}
// 簡單驗證 email 格式
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(收件人)) {
錯誤清單.push(`第 ${列號} 列:「${收件人}」不是有效的信箱`);
return;
}
try {
MailApp.sendEmail({
to: 收件人,
subject: 主旨,
body: 內容
});
成功++;
} catch (e) {
錯誤清單.push(`第 ${列號} 列:${e.message}`);
}
});
// 結果回報
let 訊息 = `寄送完成!\n成功:${成功} 封\n略過(B 欄空白):${略過} 列`;
if (錯誤清單.length > 0) {
訊息 += `\n\n失敗 ${錯誤清單.length} 筆:\n` + 錯誤清單.join('\n');
}
SpreadsheetApp.getUi().alert(訊息);
}
寄送信件() 函式還不夠,要在 onOpen() 的選單裡加上 .addItem('寄送信件', '寄送信件') 這一行(上面示範碼已加好),選單「資料匯整工具」才會出現「寄送信件」可以點。少了這一行,函式雖然存在卻無法從選單觸發。<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
body {
font-family: Arial, "Noto Sans TC", sans-serif;
padding: 20px;
color: #222;
}
h2 {
margin: 0 0 12px;
font-size: 20px;
}
p {
margin: 0 0 16px;
line-height: 1.6;
color: #555;
}
.box {
border: 1px solid #ddd;
border-radius: 8px;
padding: 16px;
background: #fafafa;
}
input {
width: 100%;
margin: 8px 0 16px;
}
button {
border: none;
border-radius: 6px;
padding: 10px 16px;
cursor: pointer;
font-size: 14px;
}
.primary {
background: #5b21b6;
color: white;
}
.secondary {
background: #e5e7eb;
color: #111;
margin-left: 8px;
}
#status {
margin-top: 16px;
color: #444;
line-height: 1.5;
}
</style>
</head>
<body>
<h2>上傳 CSV 檔</h2>
<p>請選擇三份 CSV 檔,系統會整理成:來源平台、報名編號、姓名、單位、Email。</p>
<div class="box">
<input id="csvFiles" type="file" accept=".csv,text/csv" multiple>
<button class="primary" onclick="uploadFiles()">開始匯入</button>
<button class="secondary" onclick="google.script.host.close()">取消</button>
<div id="status"></div>
</div>
<script>
function uploadFiles() {
const input = document.getElementById('csvFiles');
const status = document.getElementById('status');
const files = Array.from(input.files || []);
if (files.length === 0) {
status.textContent = '請先選擇 CSV 檔。';
return;
}
status.textContent = '讀取檔案中...';
Promise.all(files.map(readFileAsText))
.then(function (filePayloads) {
status.textContent = '匯入中,請稍候...';
google.script.run
.withSuccessHandler(function (message) {
status.textContent = message;
})
.withFailureHandler(function (error) {
status.textContent = '匯入失敗:' + error.message;
})
.importCsvFiles(filePayloads);
})
.catch(function (error) {
status.textContent = '讀取檔案失敗:' + error.message;
});
}
function readFileAsText(file) {
return new Promise(function (resolve, reject) {
const reader = new FileReader();
reader.onload = function (event) {
resolve({
name: file.name,
content: event.target.result
});
};
reader.onerror = function () {
reject(new Error(file.name + ' 讀取失敗'));
};
reader.readAsText(file, 'UTF-8');
});
}
</script>
</body>
</html>
開啟 Gemini Notebook,建立新的 notebook。
上傳兩份模擬內部文件。
先請它整理重點,再追問差異、規則、待確認事項。
看到答案後,回到引用來源確認內容。
目標是先讓 Gemini Notebook 從單一文件中整理出可行動的 checklist。
我是今天報到的新人,請根據《新人到職說明》幫我整理今天必須完成的事項,分成「一定要做」「如果來得及可以做」「需要主管協助」三類,並整理成 checklist。
目標是讓 AI 把新人到職說明與財務差旅規定串起來,看見跨文件流程。
我是到職第一週的新人,主管臨時安排我明天出差或去外部會議,但我的差勤系統和財務系統可能都還沒開通。請根據《新人到職說明》和《財務核銷與差旅規定》,整理我出發前、會議或出差中、回來後各自要注意什麼,並列出可能卡住的地方與建議處理方式。
目標是把 Gemini Notebook 從查詢工具升級成文件改善助理。
請交叉比對《新人到職說明》和《財務核銷與差旅規定》這兩份文件,找出內容中互相補充、重複、可能矛盾或容易讓新人誤解的地方。請用表格整理,欄位包含「問題類型」「相關文件或段落」「可能造成的困惑」「建議補充或修改方式」。
把今天的方法帶回工作現場:六個常見情境的提示詞直接複製就能用。提醒:貼任何內容進 AI 之前,先把玩家個資與未公開營運數據拿掉。
以下是會議逐字稿或筆記,請整理成:①三句話摘要 ②決議事項 ③行動清單(每項標負責人與期限,沒講到的標【待確認】)④待追蹤問題。 【貼上會議記錄】
以下是一則玩家反映的問題(已去除個資)與我想回覆的重點。請幫我寫成一封得體的客服回覆:先同理對方的感受,再說明處理方式與預計時程,語氣專業友善、不官腔,200 字內。 玩家反映:【貼上】 我想回覆的重點:【貼上】
請幫我寫一篇玩家活動公告。活動資訊:【活動名稱/時間/參加方式/獎勵內容】。要求:標題吸睛、開頭有梗不官腔、內文條列清楚、結尾提醒注意事項,300 字內。
以下是我這週做的事(流水帳)。請整理成給主管的週報,分四區:本週成果、進行中、下週計畫、需要協助,每區最多 3 點,用詞精簡。 【貼上流水帳】
以下是一段散亂的資料(訊息、信件或筆記混在一起)。請整理成表格,欄位由你依內容判斷,缺漏的欄位標【缺】,最後告訴我哪些資料可能有問題需要人工確認。 【貼上散亂資料】
請幫我整理【某款遊戲/某個產品】近一個月的玩家口碑與討論熱點:主要好評、主要抱怨、討論聲量的變化,每點附上來源連結,用表格呈現。
課後想繼續玩,從這四個入口出發。
附來源的 AI 搜尋引擎:查產業趨勢、競品輿情、事實查證都好用,每個答案都附引用連結,點回原始出處確認。
GitHub 上的 Nano Banana(Gemini 生圖)案例集:大量生圖範例附完整提示詞與成品對照,看到喜歡的直接抄回家改。
依用途分類的 GPT Image 2 提示詞庫:海報、插畫、App 與網頁視覺都有現成範例,找靈感、學寫法都方便。
把今天學的「模板化」再往前推一步:可以建立自己的 Skill(常用任務範本)與知識庫,讓 AI 帶著你的工作方法與資料回答問題,個人或團隊都容易上手的 AI 工作平臺。