向 Google 电子表格提交表单
最近,我创建了一个 HTML 表单,将结果发送到 Google 电子表格。我用它来进行分析,但即使只是用来跟踪表单的结果,它也非常有用。在尝试了各种解决方案,甚至在 Google 上搜索了超过第二页之后,我找到了一个对我有用的方法,我觉得值得分享。
先决条件: HTML 和基本的 JavaScript 知识。
该解决方案的功劳归于Jamie Wilson,他创建了该解决方案并将其上传到Github。
首先,创建电子表格
- 前往Google 表格并
Start a new spreadsheet
使用Blank
模板。免责声明:文件命名方式无关紧要。 - 在第一行,第一列写时间戳,第二列写电子邮件。
创建 Google Apps 脚本
- 单击
Tools > Script Editor…
即可打开一个新选项卡。 - 为脚本命名
Submit Form to Google Sheets
,或者以任何您想记住的脚本功能来命名。 - 删除标签
function myFunction() {}
内的块Code.gs
。 - 将以下脚本粘贴到其位置并
File > Save
:
var sheetName = 'Sheet1'
var scriptProp = PropertiesService.getScriptProperties()
function intialSetup () {
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
scriptProp.setProperty('key', activeSpreadsheet.getId())
}
function doPost (e) {
var lock = LockService.getScriptLock()
lock.tryLock(10000)
try {
var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
var sheet = doc.getSheetByName(sheetName)
var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
var nextRow = sheet.getLastRow() + 1
var newRow = headers.map(function(header) {
return header === 'timestamp' ? new Date() : e.parameter[header]
})
sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow])
return ContentService
.createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow }))
.setMimeType(ContentService.MimeType.JSON)
}
catch (e) {
return ContentService
.createTextOutput(JSON.stringify({ 'result': 'error', 'error': e }))
.setMimeType(ContentService.MimeType.JSON)
}
finally {
lock.releaseLock()
}
}
如果您想更好地理解此脚本的作用,请查看
form-script-commented.js
repo 中的文件以获得详细说明。
运行设置功能
- 现在,去
Run > Run Function > initialSetup
运行这个函数。 - 在
Authorization Required
对话框中,单击Review Permissions
。 - 登录或选择与此项目关联的 Google 帐户。
- 您应该会看到一个对话框,其中显示
Hi {Your Name}, Submit Form to Google Sheets wants to...
- 然后点击
Allow
添加新项目触发器
- 点击
Edit > Current project’s triggers
。 - 在对话框中单击
No triggers set up. Click here to add one now
。 - 在下拉菜单中选择
doPost
- 将事件字段设置为
From spreadsheet
和On form submit
- 然后点击
Save
将项目发布为 Web 应用
- 点击
Publish > Deploy as web app…
。 - 设置
Project Version
为New
并输入initial version
到下面的输入字段中。 - 保留
Execute the app as:
设置为Me(your@address.com)
。 - 对于
Who has access to the app:
选择Anyone, even anonymous
。 - 点击
Deploy
。 Current web app URL
在弹出窗口中,从对话框中复制。- 然后点击
OK
。
重要提示!如果您的 Gmail 使用了自定义域名,您可能需要点击“确定”,刷新页面,然后
Publish > Deploy as web app…
再次访问以获取正确的 Web 应用 URL。它应该类似于https://script.google.com/a/yourdomain.com/macros/s/XXXX…
。
输入您的 Web 应用 URL
打开名为 的文件index.html
。在第 7 行将以下内容替换<SCRIPT URL>
为您的脚本 URL:
<form name="submit-to-google-sheet">
<input name="email" type="email" placeholder="Email" required>
<button type="submit">Send</button>
</form>
<script>
const scriptURL = '<SCRIPT URL>'
const form = document.forms['submit-to-google-sheet']
form.addEventListener('submit', e => {
e.preventDefault()
fetch(scriptURL, { method: 'POST', body: new FormData(form)})
.then(response => console.log('Success!', response))
.catch(error => console.error('Error!', error.message))
})
</script>
如您所见,此脚本使用了Fetch API,这是一种基于 Promise 的较新的 Web 请求机制。它向您的脚本 URL 发出“POST”请求,并使用FormData将我们的数据作为 URL 参数传递。
添加额外的表单数据
要捕获其他数据,您只需创建新列,其标题与name
表单输入的值完全匹配。例如,如果您想添加姓氏和名字输入,您可以name
像这样赋值:
<form name="submit-to-google-sheet">
<input name="email" type="email" placeholder="Email" required>
<input name="firstName" type="text" placeholder="First Name">
<input name="lastName" type="text" placeholder="Last Name">
<button type="submit">Send</button>
</form>
然后,您可以创建新的标题,其中包含精确且区分大小写的name
值。只需打开电子表格,将名称添加到第一行,每个名称位于不同的列中。
相关 Polyfill
其中一些功能尚未完全被浏览器支持,或者在较旧的浏览器上无法使用。以下是一些 polyfill 选项,可用于提供更好的支持。
由于 FormData polyfill 是以 Node 包的形式发布的,需要编译才能在浏览器中使用,因此使用Browserify 的 CDN wzrd.in是一个不错的选择。该服务会为我们编译、压缩并提供这些脚本的最新版本。
您需要确保这些内容在主脚本处理表单提交之前加载。例如:
<script src="https://wzrd.in/standalone/formdata-polyfill"></script>
<script src="https://wzrd.in/standalone/promise-polyfill@latest"></script>
<script src="https://wzrd.in/standalone/whatwg-fetch@latest"></script>
<script>
const scriptURL = '<SCRIPT URL>'
const form = document.forms['submit-to-google-sheet']
...
</script>
然后……没错,就是这个。
我尝试了好几种不同的方法来完成这个“简单”的动作,只有这个方法对我有用——希望它能帮到你。欢迎分享/保存以备将来使用,如果你有改进的想法,也欢迎留言!