【问题标题】:How do I make use of an external html form to upload file to google drive and save other form data to google sheets?如何使用外部 html 表单将文件上传到谷歌驱动器并将其他表单数据保存到谷歌表格?
【发布时间】:2021-11-07 15:46:15
【问题描述】:

我正在尝试改编本教程:https://tanaikech.github.io/2020/08/13/uploading-file-to-google-drive-from-external-html-without-authorization/

专门用于将文件上传到谷歌驱动器,以包含要保存在谷歌工作表中的文本字段数据。

哪位好心人能帮帮我:(

这是我的电子表格中的内容:

这是 GAS 代码:

    var sheetName = 'Sheet1'
    var scriptProp = PropertiesService.getScriptProperties()

    function intialSetup () {
      var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet()
      scriptProp.setProperty('key', activeSpreadsheet.getId())
    }

   function doPost(e) {

      const folderId = "root"; // Folder ID which is used for putting the file.
      const blob = Utilities.newBlob(
        JSON.parse(e.postData.contents),
        e.parameter.mimeType,
        e.parameter.filename
      );
  const file = DriveApp.getFolderById(folderId).createFile(blob);
  const responseObj = {
    filename: file.getName(),
    fileId: file.getId(),
    fileUrl: file.getUrl(),
  };

  var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
    var sheet = doc.getSheetByName(sheetName)

    var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
    var range = sheet.getRange("A1:A").getValues();
    var filtered_r = range.filter(String).length;

    var newRow = headers.map(function(header) { // newRow is possibly a literally object where the keys are the headers and values are the user input
      if(header === "file"){
        e.parameter[header] = responseObj.fileUrl;
      }
      return e.parameter[header];
    })
  
    sheet.getRange(filtered_r + 1, 1, 1, newRow.length).setValues([newRow]);





  return ContentService.createTextOutput(
    JSON.stringify(responseObj)
  ).setMimeType(ContentService.MimeType.JSON);
}

这是外部html代码(不是在GAS项目中制作的,这就是我不能使用google.script.run方法的原因)

<form id="form">
  <input type="text" name="hobby">
  <input name="file" id="uploadfile" type="file" />
  <input id="submit" type="submit" />
</form>

<script>
  const form = document.getElementById("form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    const file = form.file.files[0];
    const fr = new FileReader();
    fr.readAsArrayBuffer(file);
    fr.onload = (f) => {

        
      const url = "https://script.google.com/macros/s/###/exec"; // Please set the URL of Web Apps.

      const qs = new URLSearchParams({
        filename: file.name,
        mimeType: file.type,
      });

      
      fetch(`${url}?${qs}`, {
        method: "POST",
        body: JSON.stringify([...new Int8Array(f.target.result)]), // is it possible to change this value to  new FormData(form)?
      })
        .then((res) => res.json())
        .then(console.log)
        .catch(console.log);
    };
  });
</script>

【问题讨论】:

  • 使用 web 应用程序和从外部网站执行此操作有很大区别,归结为您知道多少 javascript。
  • 有问题吗?见minimal reproducible example——尤其是关于“描述”的部分
  • 首先,对于我的示例脚本对您的情况没有用处,我深表歉意。对于您的问题,我提出了一个修改后的脚本作为答案。你能确认一下吗?如果这没有用,我再次道歉。

标签: javascript html google-apps-script


【解决方案1】:

我相信你的目标如下。

  • 您想上传来自&lt;input name="file" id="uploadfile" type="file" /&gt; 的文件和来自&lt;input type="text" name="hobby"&gt; 的值。

当我看到您的脚本时,该文件被发送到 Web 应用程序。但是,不会发送来自&lt;input type="text" name="hobby"&gt; 的值。我认为这可能是您的问题的原因。为了解决这个问题,修改后的脚本如下。

修改后的脚本:

Google Apps 脚本方面:

在这次修改中,doPost被修改了。

function doPost(e) {
  const obj = JSON.parse(e.postData.contents);
  const folderId = "root"; // Folder ID which is used for putting the file.
  const blob = Utilities.newBlob(
    obj.file,
    e.parameter.mimeType,
    e.parameter.filename
  );
  const file = DriveApp.getFolderById(folderId).createFile(blob);
  const responseObj = {
    filename: file.getName(),
    fileId: file.getId(),
    fileUrl: file.getUrl(),
  };
  obj.file = responseObj.fileUrl;
  var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'))
  var sheet = doc.getSheetByName(sheetName)
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
  var range = sheet.getRange("A1:A").getValues();
  var filtered_r = range.filter(String).length;
  var newRow = headers.map(function (header) {
    return obj[header];
  });
  sheet.getRange(filtered_r + 1, 1, 1, newRow.length).setValues([newRow]);
  return ContentService.createTextOutput(
    JSON.stringify(responseObj)
  ).setMimeType(ContentService.MimeType.JSON);
}

HTML & Javascript 方面:

<form id="form">
  <input type="text" name="hobby" id="sample" /> <!-- Modified -->
  <input name="file" id="uploadfile" type="file" />
  <input id="submit" type="submit" />
</form>

<script>
  const form = document.getElementById("form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    const file = form.file.files[0];
    const fr = new FileReader();
    fr.readAsArrayBuffer(file);
    fr.onload = (f) => {
      const url = "https://script.google.com/macros/s/###/exec"; 
      const qs = new URLSearchParams({
        filename: file.name,
        mimeType: file.type,
      });
      fetch(`${url}?${qs}`, {
        method: "POST",
        body: JSON.stringify({file: [...new Int8Array(f.target.result)], hobby: document.getElementById("sample").value}),
      })
        .then((res) => res.json())
        .then(console.log)
        .catch(console.log);
    };
  });
</script>

注意:

补充:

在我发布了您使用的示例脚本https://tanaikech.github.io/2020/08/13/uploading-file-to-google-drive-from-external-html-without-authorization/ 之后,我还发布了一个用于解析 HTML 表单以与 Google Apps 脚本一起使用的 Javascript 库。 Ref使用这个库时,你的脚本如下。

示例脚本:

Google Apps 脚本方面:

在这次修改中,doPost被修改了。

function doPost(e) {
  const obj = JSON.parse(e.postData.contents);
  const folderId = "root"; // Folder ID which is used for putting the file.
  const f = obj.file[0].files[0];
  const blob = Utilities.newBlob(
    f.bytes,
    f.mimeType,
    f.filename
  );
  const file = DriveApp.getFolderById(folderId).createFile(blob);
  const responseObj = {
    filename: file.getName(),
    fileId: file.getId(),
    fileUrl: file.getUrl(),
  };
  obj.file = [{ value: responseObj.fileUrl }];
  var doc = SpreadsheetApp.openById(scriptProp.getProperty('key'));
  var sheet = doc.getSheetByName(sheetName)
  var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0]
  var range = sheet.getRange("A1:A").getValues();
  var filtered_r = range.filter(String).length;
  var newRow = headers.map(function (header) {
    return obj[header][0].value;
  })
  sheet.getRange(filtered_r + 1, 1, 1, newRow.length).setValues([newRow]);
  return ContentService.createTextOutput(
    JSON.stringify(responseObj)
  ).setMimeType(ContentService.MimeType.JSON);
}

HTML & Javascript 方面:

<form id="form">
  <input type="text" name="hobby" id="sample" /> <!-- Modified -->
  <input name="file" id="uploadfile" type="file" />
  <input id="submit" type="submit" />
</form>

<script src="https://cdn.jsdelivr.net/gh/tanaikech/HtmlFormObjectParserForGoogleAppsScript_js@master/htmlFormObjectParserForGoogleAppsScript_js.min.js"></script>
<script>
  const url = "https://script.google.com/macros/s/###/exec";
  const form = document.getElementById("form");
  form.addEventListener("submit", async (e) => {
    e.preventDefault();
    const obj = await ParseFormObjectForGAS(form);
    fetch(url, {
      method: "POST",
      body: JSON.stringify(obj),
    })
    .then((res) => res.json())
    .then(console.log)
    .catch(console.log);
  });
</script>

参考:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多