javascript - 如何将图像和文本输入上传到同一行到谷歌表格
问题描述
嗨,我正在创建一个谷歌脚本网络应用程序,它将上传 10 张照片,每张照片都有评论,当在网络应用程序上按下上传时,这些信息将被插入到谷歌工作表中,这样我就可以将每张照片上传到电子表格中的正确位置但由于缺乏 HTML 知识,我无法获取评论,还尝试显示一些通知/进度,以便我能够判断该过程已完成。请参阅下面的代码和 HTML 也是目标 google 表的链接https://docs.google.com/spreadsheets/d/1r8vt9cMLvJ68AI6xu51sodkL6_j6tP_Y86cXEJOrvuQ/edit?usp=sharing
索引.HTML:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
</head>
<body>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment1" name="Location">
<label for="message">Notes </label>
<textarea name="message"id="note1" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment2" name="Location">
<label for="message">Notes </label>
<textarea name="message" id="note2" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment3" name="Location">
<label for="message">Notes </label>
<textarea name="message" id="note3" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment4" name="Location">
<label for="message">Notes </label>
<textarea name="message"id="note4" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment5" name="Location">
<label for="message">Notes </label>
<textarea name="message" id="note5" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment6" name="Location">
<label for="message">Notes </label>
<textarea name="message" id="note6" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment7" name="Location">
<label for="message">Notes </label>
<textarea name="message" id="note7" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment8" name="Location">
<label for="message">Notes </label>
<textarea name="message" id="note8" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment9" name="Location">
<label for="message">Notes </label>
<textarea name="message" id="note9" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<input name="file" id="files" type="file" multiple>
<label for="fname">Location </label>
<input type="text" id="comment10" name="Location">
<label for="message">Notes </label>
<textarea name="message"id="note10" style="width:200px; height:50px;"> </textarea>
<br>
<br>
<br>
<input type='button' value='Upload' onclick='getFiles()'>
<script>
function getFiles() {
// const f = document.getElementById('files');
const fAll= document.querySelectorAll("#files");
var commentList= ["comment1","comment2","comment3","comment4","comment5","comment6","comment7","comment8","comment9","comment10"];
for (var i = 0; i < commentList.length; i++) {
var comment = document.getElementById(commentList[i]);
}
const noteList= ["note1","note2","note3","note4","note5","note6","note7","note8","note9","note10"];
console.log(comment)
fAll.forEach(function(f){
[...f.files].forEach((file, i) => {
const fr = new FileReader();
fr.onload = (e) => {
const data = e.target.result.split(",");
const obj = {fileName: f.files[i].name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]};
google.script.run.withSuccessHandler((id) => {
console.log(id);
}).saveFile(obj,comment);
}
fr.readAsDataURL(file);
});
})
}
</script>
</body>
</html>
代码.GS:
function doGet() {
return HtmlService.createHtmlOutputFromFile('index');
}
function saveFile(obj,comment) {
var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, obj.fileName);
var file=DriveApp.createFile(blob);
var fileId= file.getId()
//return fileId
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK,DriveApp.Permission.VIEW);
var fileUrl = "https://drive.google.com/uc?export=view&id="+fileId;
Logger.log(fileUrl);
//var url=/* Google sheet URL */;
var ss= SpreadsheetApp.openByUrl(url);
var ws= ss.getSheetByName("Photos Report");
var newurls = '=image("'+fileUrl+'",2)';
ws.appendRow([null,newurls, new Date(),comment]);
return ContentService.createTextOutput("Success").setMimeType(ContentService.MimeType.JAVASCRIPT);
}
解决方案
我相信你的目标如下。
- 您想让用户上传 10 张图片并输入 10 条评论和 10 条注释,并且您希望将图片保存到 Google Drive 并将图片、图片的 URL、评论和注释放到 Google 电子表格中。
修改点:
- 在您的脚本中,
google.script.run
每个循环都运行。 comment
是一个对象。- 在这种情况下,在您的 中
google.script.run
,使用了一个comment
对象。
- 在这种情况下,在您的 中
noteList
未使用。- 当您想
querySelectorAll
在 HTML 中使用 , 时,我认为可以使用它检索所有值。 - 当在 Javascript 端检索所有值并通过一次调用将它们发送到 Google Apps Script 时,我认为这会降低流程成本。
- 在
saveFile
Google Apps 脚本方面,在您的情况下,该值以google.script.run
. 所以return ContentService.createTextOutput("Success").setMimeType(ContentService.MimeType.JAVASCRIPT);
不需要。您可以使用return "Success";
.
当以上几点反映到您的脚本时,它变成如下。
修改后的脚本:
HTML&Javascript 方面:
请修改您<script>,,,</script>
的如下。
<script>
function getFiles() {
const files = document.querySelectorAll("#files"); // or document.querySelectorAll("input[type='file']")
const comments = document.querySelectorAll("input[type='text']");
const notes = document.querySelectorAll("textarea");
const ar = [...files].map((f, i) => ({file: f.files[0], comment: comments[i].value, note: notes[i].value}));
Promise.all(ar.map(({file, comment, note}, i) => {
const fr = new FileReader();
return new Promise(r => {
if (file) {
fr.onload = e => {
const data = e.target.result.split(",");
r({file: {fileName: file.name, mimeType: data[0].match(/:(\w.+);/)[1], data: data[1]}, comment: comment, note: note});
}
fr.readAsDataURL(file);
} else {
r({file: null, comment: comment, note: note});
}
});
}))
.then(obj => {
google.script.run.withSuccessHandler(e => console.log(e)).saveFile(obj);
});
}
</script>
- 在此修改后的脚本中,从
upload 10 photos
您的问题中,从每个文件输入标签中检索一个文件。
Google Apps 脚本方面:
请修改您saveFile()
的如下。
function saveFile(obj) {
const values = obj.map(({file, comment, note}) => {
if (file) {
var blob = Utilities.newBlob(Utilities.base64Decode(file.data), file.mimeType, file.fileName);
var file = DriveApp.createFile(blob);
var fileId = file.getId();
file.setSharing(DriveApp.Access.ANYONE_WITH_LINK,DriveApp.Permission.VIEW);
var fileUrl = "https://drive.google.com/uc?export=view&id="+fileId;
var newurls = '=image("'+fileUrl+'",2)';
return ["", newurls, new Date(), note, comment];
}
return ["", "", new Date(), note, comment];
});
var ss = SpreadsheetApp.getActiveSpreadsheet(); // or var ss = SpreadsheetApp.openByUrl(url);
var ws = ss.getSheetByName("Photos Report");
ws.getRange(ws.getLastRow() + 1, 1, values.length, values[0].length).setValues(values);
return "Success";
}
- 在您的示例电子表格中,设置了“照片、日期、注释”而未设置“评论”。但是,在您的问题中,您似乎想要放置“注释”和“评论”。所以我添加了它们。
- 在您的示例电子表格中,该脚本是容器绑定脚本。所以我认为
SpreadsheetApp.getActiveSpreadsheet()
可以使用SpreadsheetApp.openByUrl(url)
. 但是,如果您想将值放到其他电子表格中,请使用SpreadsheetApp.openByUrl(url)
.
笔记:
- 在您的情况下,使用了 Web 应用程序。因此,当您修改 Web Apps 的脚本时,请将 Web Apps 重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。请注意这一点。
参考:
推荐阅读
- shell - 使用没有文件的 privet SSH 密钥
- spring-boot - 如何将 JobParameters 传递给 Spring Cloud Task 启动的批处理作业?
- scala - 具有连接操作的随机整数的 UDF 的意外行为
- python - 从 tensorflow 打印输出的问题,特定于 C api
- html - caddy webserver - 网站域配置
- c# - ASP.NET Core 中的星级评定
- php - SQLSTATE [42S02]:未找到基表或视图:1146 表“laravel_abonamenty2.currencies”不存在
- python - HTML 输出在使用 BeautifulSoup 解析后会失真
- python - 在 QPixMap 上绘制矩形:第一次单击定义第一个角,移动鼠标并继续绘制,第二次单击定义形状
- java - 如何更改 UAT 服务器 (logback.xml) 中 logging.file 的路径?