學校今年大約有 10 幾位代課老師需要代課簽到單,
看到教學組都會花時間在手動修改日期和列印這個簽到單,
於是想說有沒有比較好的方法可以稍微節省一下教學組的時間。
於是就出現了這個啦!
不過這次的問題,
在於設計好剛好 Googel 文件一頁的表格,
想不到套印複製到新檔案後,就變成預設邊界,
導致表格就跑版無法在一個頁面上。
雖然 Gemini 也有提供相關的設定方式,
但一直卡在新檔案的邊界無法如願設定。
所以腦海中就換了另一個想法,如果我先設定好一個目標檔案的邊界,
再將套印的資料複製過去不知是否可行, Yes ! 想不到就搞定了!
一起來看成果吧!!
🎯 程式使用方法:
需準備一個 Google試算表:Google試算表ID
Google試算表檔案下載(套印名字、日期函數)
=TEXT(WEEKDAY(A1),"ddd")
=CHOOSE(WEEKDAY(A1),"日","一","二","三","四","五","六")
二個Google文件檔案:Google文件範本ID、套印目標Google文件ID
// --- 設定全域變數 ---
var spreadsheetId = 'Google試算表ID';
var templateDocumentId = 'Google文件範本ID';
var targetDocumentId = '套印目標Google文件ID';
function onOpen() {
var ui = SpreadsheetApp.getUi();
ui.createMenu('🚀自訂選單')
.addItem('📄開啟範本文件', 'openTemplateDocumentLink')
.addItem('📆顯示假日', 'showWeekends')
.addItem('📅隱藏假日', 'hideWeekends')
.addSeparator()
.addItem('🎯合併所有資料', 'mergeDataToPages')
.addItem('🗑️刪除文件內容', 'clearTargetDocument')
.addToUi();
}
function showWeekends() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
sheet.showRows(1, sheet.getMaxRows());
}
function hideWeekends() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getActiveSheet();
const lastRow = sheet.getLastRow();
const dateColumn = 1; // 假設日期在 A 欄
for (let i = 1; i <= lastRow; i++) {
const date = sheet.getRange(i, dateColumn).getValue();
const dayOfWeek = new Date(date).getDay(); // 0 是星期日,6 是星期六
if (dayOfWeek === 0 || dayOfWeek === 6) {
sheet.hideRows(i);
}
}
}
function mergeDataToPages() {
var placeholder = '{{姓名}}';
// --- 錯誤處理:檢查檔案是否存在 ---
try {
SpreadsheetApp.openById(spreadsheetId);
DriveApp.getFileById(templateDocumentId);
DocumentApp.openById(targetDocumentId);
} catch (e) {
SpreadsheetApp.getActiveSpreadsheet().toast('檔案不存在,請確認 ID 是否正確', '錯誤');
return;
}
// --- 取得 Google 試算表資料 ---
var ss = SpreadsheetApp.openById(spreadsheetId);
var sheet = ss.getSheetByName('工作表1');
var data = sheet.getRange('A2:A').getValues().filter(row => row[0] !== "");
// --- 取得目標文件 ---
var targetDoc = DocumentApp.openById(targetDocumentId);
var targetBody = targetDoc.getBody();
// --- 取得 Google 文件範本檔案 ---
var templateFile = DriveApp.getFileById(templateDocumentId);
var templateDoc = DocumentApp.openById(templateFile.getId());
var templateBody = templateDoc.getBody();
// --- 移除範本文件最上方的空白段落 ---
var firstElement = templateBody.getChild(0);
if (firstElement.getType() === DocumentApp.ElementType.PARAGRAPH && firstElement.getText().trim() === "") {
templateBody.removeChild(firstElement);
}
// --- 顯示合併中視窗 ---
var htmlOutput = HtmlService.createHtmlOutput('<p>資料合併中,請稍候...</p>');
var ui = SpreadsheetApp.getUi();
var dialog = ui.showModelessDialog(htmlOutput, '合併中');
// --- 顯示合併進度 ---
SpreadsheetApp.getActiveSpreadsheet().toast('開始合併...', '合併進度');
// --- 套印資料 ---
for (var i = 0; i < data.length; i++) {
if (data[i][0] !== "") {
// --- 複製範本內容到目標文件 ---
var templateElements = templateBody.getNumChildren();
for (var j = 0; j < templateElements; j++) {
var element = templateBody.getChild(j).copy();
// --- 立即將資料複製到目標文件 ---
if (element.getType() === DocumentApp.ElementType.TABLE) {
var table = element;
for (var r = 0; r < table.getNumRows(); r++) {
for (var c = 0; c < table.getRow(r).getNumCells(); c++) {
var cell = table.getRow(r).getCell(c);
cell.replaceText(placeholder, data[i][0]);
}
}
targetBody.appendTable(table); // 使用 appendTable() 附加表格
} else if (element.getType() === DocumentApp.ElementType.PARAGRAPH) {
targetBody.appendParagraph(element); // 使用 appendParagraph() 附加段落
} else if (element.getType() === DocumentApp.ElementType.LIST_ITEM) {
targetBody.appendListItem(element); // 使用 appendListItem() 附加清單項目
} else {
// 如果是其他未處理的元素類型,則顯示警告訊息
Logger.log('未處理的元素類型:' + element.getType());
}
}
// --- 從第二次執行開始,且非最後一次執行時插入分頁符號 ---
if (i > 0 && i < data.length - 1) {
targetBody.appendPageBreak();
}
// --- 更新合併進度 ---
SpreadsheetApp.getActiveSpreadsheet().toast(`已合併 ${i + 1}/${data.length}`, '合併進度');
}
}
// --- 移除文件最後的空白頁 ---
var lastChild = targetBody.getChild(targetBody.getNumChildren() - 1);
if (lastChild.getType() == DocumentApp.ElementType.PAGE_BREAK) {
targetBody.removeChild(lastChild);
}
// --- 合併完成訊息 ---
SpreadsheetApp.getActiveSpreadsheet().toast('合併完成!', '合併進度');
// --- 關閉「合併中」視窗 ---
ui.alert('合併完成');
// --- 開啟目標檔案的連結 ---
var targetFileLink = `https://docs.google.com/document/d/${targetDocumentId}/edit`;
// --- 建立 HTML 輸出並開啟目標檔案視窗 ---
var htmlOutput = HtmlService.createHtmlOutput(`
<script>
window.open('${targetFileLink}', '_blank');
google.script.host.close();
</script>
`);
// --- 顯示開啟目標檔案的對話方塊 ---
ui.showModalDialog(htmlOutput, '開啟目標檔案');
}
function openTemplateDocumentLink() {
var templateFileLink = `https://docs.google.com/document/d/${templateDocumentId}/edit`;
var htmlOutput = HtmlService.createHtmlOutput(`
<script>
window.open('${templateFileLink}', '_blank');
google.script.host.close();
</script>
`);
SpreadsheetApp.getUi().showModalDialog(htmlOutput, '開啟範本檔案');
}
function clearTargetDocument() {
// --- 錯誤處理:檢查檔案是否存在 ---
try {
DocumentApp.openById(targetDocumentId);
} catch (e) {
SpreadsheetApp.getActiveSpreadsheet().toast('檔案不存在,請確認 ID 是否正確', '錯誤');
return;
}
var targetDoc = DocumentApp.openById(targetDocumentId);
var targetBody = targetDoc.getBody();
targetBody.clear();
SpreadsheetApp.getActiveSpreadsheet().toast('目標文件已清空!', '完成');
Browser.msgBox('目標文件已清空!');
}
快來試試吧~~
沒有留言:
張貼留言
歡迎大家一起留言討論!