如何升级Google Forms插件,支持用户配置Sheet信息并复用配置?
插件升级技术实现方案
一、支持非本人用户配置Sheet信息
1. 构建配置UI(侧边栏/弹窗)
用HtmlService创建带交互的配置界面,包含SheetID输入框、SheetName输入框、「从Drive选择表格」按钮和「保存配置」按钮。示例UI代码(存为config.html):
<!DOCTYPE html> <html> <body> <div style="padding:10px;"> <label>表格ID:</label> <input type="text" id="sheetId" placeholder="输入Google表格ID" style="width:100%;margin:5px 0;"><br> <label>工作表名称:</label> <input type="text" id="sheetName" placeholder="输入工作表名称" style="width:100%;margin:5px 0;"><br> <button onclick="openDrivePicker()" style="margin-right:10px;">从Drive选择表格</button> <button onclick="saveConfig()">保存配置</button> </div> <script> function openDrivePicker() { google.script.run.withSuccessHandler(data => { document.getElementById('sheetId').value = data.id; document.getElementById('sheetName').value = 'Sheet1'; // 默认工作表名,可按需调整 }).getDrivePickerAuth(); } function saveConfig() { const sheetId = document.getElementById('sheetId').value.trim(); const sheetName = document.getElementById('sheetName').value.trim(); if (!sheetId || !sheetName) { alert('请填写完整配置信息'); return; } google.script.run.withSuccessHandler(() => { alert('配置保存成功'); }).saveFormConfig(sheetId, sheetName); } </script> </body> </html>
2. 配置存储与读取
使用PropertiesService.getDocumentProperties()将配置绑定到当前Form(每个Form独立存储),修改原有代码适配动态配置:
// 打开配置侧边栏 function openConfigSidebar() { const html = HtmlService.createHtmlOutputFromFile('config.html').setTitle('Sheet配置'); FormApp.getUi().showSidebar(html); } // 保存配置到当前Form的文档属性 function saveFormConfig(sheetId, sheetName) { const props = PropertiesService.getDocumentProperties(); props.setProperties({ 'TARGET_SHEET_ID': sheetId, 'TARGET_SHEET_NAME': sheetName }); } // 修改getQuestionValues,从配置中读取Sheet信息 function getQuestionValues() { const props = PropertiesService.getDocumentProperties(); const sheetId = props.getProperty('TARGET_SHEET_ID'); const sheetName = props.getProperty('TARGET_SHEET_NAME'); if (!sheetId || !sheetName) { throw new Error('请先通过侧边栏配置Sheet信息'); } const ss = SpreadsheetApp.openById(sheetId); const questionSheet = ss.getSheetByName(sheetName); return questionSheet.getDataRange().getValues(); } // Drive Picker授权逻辑(需在脚本编辑器启用Drive API) function getDrivePickerAuth() { const picker = DriveApp.getRootFolder(); // 触发授权,实际Picker需结合客户端API实现 return {id: picker.getId()}; // 示例,完整Picker需补充客户端代码 }
3. 权限处理
在脚本编辑器中:
- 点击「资源」>「高级Google服务」,启用Drive API和Google Sheets API
- 首次运行时引导用户完成授权流程,确保用户拥有目标Sheet的访问权限
二、实现全局配置批量生效
1. 全局配置存储
用PropertiesService.getScriptProperties()存储全局配置(所有安装插件的Form共享,仅插件所有者可修改):
// 保存全局配置(仅插件所有者可调用) function saveGlobalConfig(sheetId, sheetName) { const props = PropertiesService.getScriptProperties(); props.setProperties({ 'GLOBAL_SHEET_ID': sheetId, 'GLOBAL_SHEET_NAME': sheetName }); }
2. 批量更新所有关联Form
方案1:基于文件夹批量同步
让用户将所有需要同步的Form放入同一个Drive文件夹,插件遍历文件夹内的Form并应用全局配置:
// 批量更新指定文件夹内的所有Form function batchUpdateFormsInFolder(folderId) { const globalProps = PropertiesService.getScriptProperties(); const globalSheetId = globalProps.getProperty('GLOBAL_SHEET_ID'); const globalSheetName = globalProps.getProperty('GLOBAL_SHEET_NAME'); if (!globalSheetId || !globalSheetName) { throw new Error('请先设置全局配置'); } const folder = DriveApp.getFolderById(folderId); const files = folder.getFilesByType(MimeType.GOOGLE_FORMS); while (files.hasNext()) { const file = files.next(); const form = FormApp.openById(file.getId()); // 应用全局配置到当前Form const formProps = PropertiesService.getDocumentProperties(form); formProps.setProperties({ 'TARGET_SHEET_ID': globalSheetId, 'TARGET_SHEET_NAME': globalSheetName }); // 立即更新表单选项 populateQuestionsForForm(form); } } // 修改populateQuestions,支持传入指定Form对象 function populateQuestionsForForm(form) { const googleSheetsQuestions = getQuestionValuesForGlobal(); const itemsArray = form.getItems(); itemsArray.forEach(item => { googleSheetsQuestions[0].forEach((header_value, header_index) => { if(header_value === item.getTitle()) { const choiceArray = []; for(let j = 1; j < googleSheetsQuestions.length; j++) { if(googleSheetsQuestions[j][header_index]) choiceArray.push(googleSheetsQuestions[j][header_index]); } item.asCheckboxItem().setChoiceValues(choiceArray); } }); }); } // 读取全局配置的Sheet数据 function getQuestionValuesForGlobal() { const globalProps = PropertiesService.getScriptProperties(); const sheetId = globalProps.getProperty('GLOBAL_SHEET_ID'); const sheetName = globalProps.getProperty('GLOBAL_SHEET_NAME'); const ss = SpreadsheetApp.openById(sheetId); const questionSheet = ss.getSheetByName(sheetName); return questionSheet.getDataRange().getValues(); }
方案2:Workspace域批量同步(管理员专属)
如果是Google Workspace域管理员,可启用Admin SDK的Forms API,批量获取域内所有Form并应用全局配置,需额外配置域级权限。
3. 自动同步机制
设置时间驱动触发器,定期拉取全局配置并更新所有关联Form:
// 创建每日凌晨3点同步的触发器 function createDailySyncTrigger() { ScriptApp.newTrigger('batchUpdateFormsInFolder') .timeBased() .everyDays(1) .atHour(3) .create(); }
内容的提问来源于stack exchange,提问作者Bysshe
相关产品推荐
相关产品推荐

