【问题标题】:Uploading photo using Google Apps Script使用 Google Apps 脚本上传照片
【发布时间】:2021-02-04 21:14:38
【问题描述】:

我想以here 的身份使用 App Scripts 和 Google Sheets 构建联系人数据

完整的应用脚本代码是here

我只需要知道如何添加联系人照片,以便将其上传到表单中,并保存在 Google 表格中(或通过 Google 表格中的链接保存在 Google 云端硬盘中)

我读了this,但它与我想要的不同。

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    我相信你的目标如下。

    • 您想将上传图片文件的功能添加到您当前的 Google Apps 脚本项目中。

    修改点:

    • 在这种情况下,
      • 请给Form.html添加<input type="file">标签。
      • 现阶段使用V8运行时,在二进制数据的情况下,Google Apps Script端无法正确解析表单对象。 Ref 所以,二进制数据(图像文件)作为字节数组发送到 Google Apps 脚本端。
      • 为此,需要在您的 Google Apps 脚本中修改 processForm 的函数。

    当以上几点反映到你的脚本中时,它变成如下。

    修改后的脚本:

    HTML 端:Form.html

    请修改Form.html如下。

    从:
    <button type="submit" class="btn btn-primary">Submit</button>
    <input class="btn btn-secondary" type="reset" value="Reset">
    
    至:
    <div><input type="file" id="file" name="file" accept="image/png,image/jpeg"></div>  <!-- Added -->
    
    <button type="submit" class="btn btn-primary">Submit</button>
    <input class="btn btn-secondary" type="reset" value="Reset">
    

    Javascript 端:JavaScript.html

    请修改JavaScript.html如下。

    从:
    function handleFormSubmit(formObject) {
      google.script.run.withSuccessHandler(createTable).processForm(formObject);
      document.getElementById("myForm").reset();
    }
    
    至:
    // I added below function. This is from https://gist.github.com/tanaikech/58d96c023468fc1922d67764251b25e0
    const parseValues = async (e) =>
      Object.assign(
        ...(await Promise.all(
          [...e].map(
            (obj) =>
              new Promise(async (res) => {
                const temp = {[obj.name]: ""};
                if (obj.type == "radio") {
                  if (obj.checked === true) {
                    temp[obj.name] = obj.value;
                  }
                } else if (obj.type == "file") {
                  const files = obj.files;
                  temp[obj.name] = await (async (files) => {
                    return await Promise.all(
                      [...files].map(
                        (file) =>
                          new Promise((resolve, reject) => {
                            const fr = new FileReader();
                            fr.onload = (f) =>
                              resolve({
                                filename: file.name,
                                mimeType: file.type,
                                bytes: [...new Int8Array(f.target.result)],
                              });
                            fr.onerror = (err) => reject(err);
                            fr.readAsArrayBuffer(file);
                          })
                      )
                    );
                  })(files).catch((err) => console.log(err));
                } else {
                  temp[obj.name] = obj.value;
                }
                res(temp);
              })
          )
        ))
      );
    
    async function handleFormSubmit(formObject) {  // Modified
      var obj = await parseValues(formObject);  // Added
      google.script.run.withSuccessHandler(createTable).processForm(obj);  // Modified
      document.getElementById("myForm").reset();
    }
    

    Google Apps 脚本端:Code.gs

    从:
    function processForm(formObject){  
      if(formObject.RecId && checkID(formObject.RecId)){//Execute if form passes an ID and if is an existing ID
        updateData(getFormValues(formObject),globalVariables().spreadsheetId,getRangeByID(formObject.RecId)); // Update Data
      }else{ //Execute if form does not pass an ID
        appendData(getFormValues(formObject),globalVariables().spreadsheetId,globalVariables().insertRange); //Append Form Data
      }
      return getLastTenRows();//Return last 10 rows
    }
    
    至:
    // I added below function.
    function saveFileToDrive(e) {
      var blob = Utilities.newBlob(e.bytes, e.mimeType, e.filename);
      var file = DriveApp.getFolderById("root").createFile(blob);  // In this case, the image is saved to the root folder. Please modify `root` to your actulal folder ID.
      return file.getDownloadUrl();
    }
    
    function processForm(formObject){
    
      var fileLink = formObject.file.length > 0 ? saveFileToDrive(formObject.file[0]) : "";  // Added
    
      if(formObject.RecId && checkID(formObject.RecId)){//Execute if form passes an ID and if is an existing ID
        updateData(getFormValues(formObject),globalVariables().spreadsheetId,getRangeByID(formObject.RecId)); // Update Data
      }else{ //Execute if form does not pass an ID
        appendData(getFormValues(formObject),globalVariables().spreadsheetId,globalVariables().insertRange); //Append Form Data
      }
      return getLastTenRows();//Return last 10 rows
    }
    
    • 当上述修改反映到您的 Google Apps 脚本项目时,当您打开 Web 应用程序时,您可以看到文件输入标签。当您选择一个图像文件并单击按钮时,表单对象由parseValues() 的函数解析,并将解析的对象发送到 Google Apps Script 端。在 Google Apps Script 端,上传图片文件时,图片数据以文件形式保存到 Google Drive,下载链接返回为fileLink
    • 关于fileLink的取值,请根据自己的实际情况修改脚本使用。

    注意:

    • 从您的脚本看来,您正在使用 Web 应用程序。 因此,当您修改脚本时,请将 Web 应用程序重新部署为新版本。这样,最新的脚本就会反映到 Web 应用程序中。请注意这一点。
    • 这是一个简单的修改。所以请根据您的实际情况修改HTML的样式和放入Google电子表格的值。
    • 在您的问题请求中,您说I just need to know how can I add the contact PHOTO, so it is getting uploaded in the form, and saved in the Google Sheets (or at Google Drive with link in the Google Sheets)
      • 关于这一点,当图像作为 blob 放入电子表格时,再次从电子表格中检索图像有点复杂。所以在我的回答中,我建议通过将图像数据保存为 Google Drive 上的文件来检索文件链接。

    参考资料:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-18
      • 2014-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多