首页 > 解决方案 > 如何将图像和文本输入上传到同一行到谷歌表格

问题描述

嗨,我正在创建一个谷歌脚本网络应用程序,它将上传 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);  

}

标签: javascripthtmlgoogle-apps-scriptgoogle-sheets

解决方案


我相信你的目标如下。

  • 您想让用户上传 10 张图片并输入 10 条评论和 10 条注释,并且您希望将图片保存到 Google Drive 并将图片、图片的 URL、评论和注释放到 Google 电子表格中。

修改点:

  • 在您的脚本中,google.script.run每个循环都运行。
  • comment是一个对象。
    • 在这种情况下,在您的 中google.script.run,使用了一个comment对象。
  • noteList未使用。
  • 当您想querySelectorAll在 HTML 中使用 , 时,我认为可以使用它检索所有值。
  • 当在 Javascript 端检索所有值并通过一次调用将它们发送到 Google Apps Script 时,我认为这会降低流程成本。
  • saveFileGoogle 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 应用程序中。请注意这一点。

参考:


推荐阅读