【问题标题】:Form and file upload with htmlService and app script not working使用 htmlService 和应用程序脚本上传表单和文件不起作用
【发布时间】:2014-01-13 04:24:28
【问题描述】:

我正在尝试将文件与表单数据一起上传到特定的谷歌驱动器文件夹到电子表格中。此代码的电子表格部分有效,但文件上传功能无效。任何有关解决此问题的帮助将不胜感激。

代码.gs

var submissionSSKey = 'SS ID';
function doGet(e) {
      var template = HtmlService.createTemplateFromFile('Form.html');
  template.action = ScriptApp.getService().getUrl();
  return template.evaluate();
}

function doPost(e) {
  var template = HtmlService.createTemplateFromFile('Thanks.html');
  var LoanType = template.name = e.parameter.name;
  var borrower = template.department = e.parameter.department;
  var amount = template.message = e.parameter.message;
  var emailed = template.email = e.parameter.email;
  var comp = 'N/A'

  var sheet = SpreadsheetApp.openById(submissionSSKey).getSheets()[0];
  var lastRow = sheet.getLastRow();
  var targetRange = sheet.getRange(lastRow+1, 1, 1, 5).setValues([[comp,LoanType,borrower,amount,emailed]]);

  var fileBlob = e.paramater.thefile
  var doc = DriveApp.getFolderById('folder ID');
            doc.createFile(fileBlob)//.rename('New Name');


  return template.evaluate();


}

Form.html

<html>
    <head>
        <title></title>
    </head>
    <body>
    <form action="<?= action ?>" enctype="multipart/form-data" method="post">
    <table border="0" cellpadding="1" cellspacing="0" style="width: 500px;">
    <tbody>
    <tr>
    <td>
    Name:</td>
    <td>
    <input name="name" type="text" /></td>
    </tr>
    <tr>
    <td>
    Department:</td>
    <td>
    <select name="department">
    <option>Select Option</option>
    <option>Cashier</option>
    <option>Greeter</option>
    <option>Runner</option>
    <option>Line Control</option>
    <option>IDB</option>
    <option>Unknown</option>
    </select></td>
    </tr>
    <tr>
    <td>
    Email:</td>
    <td>
    <input name="email" type="text" /></td>
    </tr>
    <tr>
    <td>
    Message:</td>
    <td>
    <textarea name="message" style="margin: 2px; height: 148px; width: 354px;"></textarea></td>
    </tr>
    <tr>
    <td>
    <p>
    School Schedule (Image Files Only):</p>
    </td>
    <td>
    <p>
    <input type="file" id="thefile" name="thefile">
    </p></td>
    </tr>
    <tr>
    <td>
    <input type="submit" value="Submit" /></td>
    <td>
    You will receive an email confirmation upon submission</td>
    </tr>
    </tbody>
    </table>
  </form></body>
</html>

Thanks.html

<html>
  <body>
    <h1>Thanks</h1>
    <p>Thank you for your submission.</p>
    Name: <?= name ?><br/>
    Department: <?= department ?><br/>
    Message: <?= message ?><br/>
    Email: <?= email ?><br/>
  </body>
</html>

【问题讨论】:

    标签: html google-apps-script google-sheets


    【解决方案1】:

    编辑:工作示例

    HtmlService 不支持 HTML 表单的 post 方法。表单收集的输入元素可以使用处理函数传递给服务器端函数。详情请见HTML Service: Communicate with Server Functions

    这是一个基于您在问题中发布的代码的示例。

    Form.html

    <script>
      // Javascript function called by "submit" button handler,
      // to show results.
      function updateOutput(resultHtml) {
        toggle_visibility('inProgress');
        var outputDiv = document.getElementById('output');
        outputDiv.innerHTML = resultHtml;
      }
      
      // From blog.movalog.com/a/javascript-toggle-visibility/
      function toggle_visibility(id) {
        var e = document.getElementById(id);
        if(e.style.display == 'block')
          e.style.display = 'none';
        else
          e.style.display = 'block';
      }
    </script>
    
    <div id="formDiv">
    <!-- Form div will be hidden after form submission -->
    <form id="myForm">
    
        Name: <input name="name" type="text" /><br/>
        Department:  <select name="department">
        <option>Select Option</option>
        <option>Cashier</option>
        <option>Greeter</option>
        <option>Runner</option>
        <option>Line Control</option>
        <option>IDB</option>
        <option>Unknown</option>
        </select><br/>
        Email: <input name="email" type="text" /><br/>
        Message: <textarea name="message" style="margin: 2px; height: 148px; width: 354px;"></textarea><br/>
        School Schedule (Image Files Only): <input name="myFile" type="file" /><br/>
      <input type="button" value="Submit"
          onclick="toggle_visibility('formDiv'); toggle_visibility('inProgress');
            google.script.run
              .withSuccessHandler(updateOutput)
              .processForm(this.parentNode)" />
    </form>
    </div>
    
    <div id="inProgress" style="display: none;">
    <!-- Progress starts hidden, but will be shown after form submission. -->
    Uploading. Please wait...
    </div>
    
    <div id="output">
      <!-- Blank div will be filled with "Thanks.html" after form submission. -->
    </div>
    

    谢谢.html

    <div>
        <h1>Thanks</h1>
        <p>Thank you for your submission.</p>
        Name: <?= name ?><br/>
        Department: <?= department ?><br/>
        Message: <?= message ?><br/>
        Email: <?= email ?><br/>
        File URL: <?= fileUrl ?><br/>
    </div>
    

    代码.gs

    var submissionSSKey = '--Spreadsheet-key--';
    var folderId = "--Folder-Id--";
    
    function doGet(e) {
      var template = HtmlService.createTemplateFromFile('Form.html');
      template.action = ScriptApp.getService().getUrl();
      return template.evaluate();
    }
    
    
    function processForm(theForm) {
      var fileBlob = theForm.myFile;
      var folder = DriveApp.getFolderById(folderId);
      var doc = folder.createFile(fileBlob);
      
      // Fill in response template
      var template = HtmlService.createTemplateFromFile('Thanks.html');
      var name = template.name = theForm.name;
      var department = template.department = theForm.department;
      var message = template.message = theForm.message;
      var email = template.email = theForm.email;     
      var fileUrl = template.fileUrl = doc.getUrl();
      
      // Record submission in spreadsheet
      var sheet = SpreadsheetApp.openById(submissionSSKey).getSheets()[0];
      var lastRow = sheet.getLastRow();
      var targetRange = sheet.getRange(lastRow+1, 1, 1, 5).setValues([[name,department,message,email,fileUrl]]);
      
      // Return HTML text for display in page.
      return template.evaluate().getContent();
    }
    

    原始答案,重点是基本调试:

    这段代码最初来自哪里?已经有multiple questions about it,看看它的原始教程或示例可能会有所帮助。

    当您将此代码作为已发布的 Web 应用程序运行并提交文件时,您收到的错误是 TypeError: Cannot read property "thefile" from undefined. 无需更多挖掘,这会告诉您在您的代码中使用了一个 undefined 对象。那是什么物体?还不知道,但一个线索是代码正在寻找一个名为 "thefile" 的属性。

    如果您在编辑器中打开了脚本,并从那里启动了 Web 应用程序(通过单击“发布/部署为 Web 应用程序”对话框中的 Test web app for your latest code),那么您还可以查看执行记录以了解更多详细信息。 (在查看菜单下)您会发现它包含如下内容:

    [13-12-25 07:49:12:447 EST] Starting execution
    [13-12-25 07:49:12:467 EST] HtmlService.createTemplateFromFile([Thanks.html]) [0 seconds]
    [13-12-25 07:49:12:556 EST] SpreadsheetApp.openById([--SSID--]) [0.089 seconds]
    [13-12-25 07:49:12:557 EST] Spreadsheet.getSheets() [0 seconds]
    [13-12-25 07:49:12:626 EST] Sheet.getLastRow() [0.067 seconds]
    [13-12-25 07:49:12:627 EST] Sheet.getRange([1, 1, 1, 5]) [0 seconds]
    [13-12-25 07:49:12:629 EST] Range.setValues([[[N/A, , Select Option, , ]]]) [0.001 seconds]
    [13-12-25 07:49:12:983 EST] Execution failed: TypeError: Cannot read property "thefile" from undefined. (line 20, file "Code") [0.17 seconds total runtime]
    

    我们看到了同样的错误,但现在我们知道了行号。该行包含拼写错误:

    var fileBlob = e.paramater.thefile
                     ^^^^^^^^^
    

    【讨论】:

    • 您对从“index”到“form”的文件名完全正确,这是我在问这个问题时犯的一个错误。此外,虽然我对拼写“参数”错误感到非常愚蠢,但我的代码仍然无法正常工作。这是现在的执行记录:[13-12-25 08:28:39:067 MST] 执行失败:找不到方法 createFile((class))。 (第 23 行,文件“代码”)[1.735 秒总运行时间]
    • 顺便说一句,代码来自用户在此站点上提出的问题。 stackoverflow.com/questions/15261247/…
    • 啊,这有点清楚了 - 那个问题是使用 UiService,而您使用 HtmlService 作为您的表单。但是,您保留了相同的服务器端后期处理。根据来自 GAS 团队成员的this answer 的说法,“HtmlService 甚至不使用 doPost - 它只使用 google.script.run 语法。” This follow up answer 有一个使用 HtmlService 和服务器端处理程序来完成文件上传的 UiService POST 的示例。
    • 我已经用一个使用 htmlservice 的工作示例更新了答案。
    • 非常感谢您! toggle_visibility 脚本是一个漂亮的小工具。我继续将style="display: block; 添加到id="formDiv" 部分,以便它在提交点击时消失。这正是我所需要的。我还在id="inProgress" 部分添加了&lt;img src="https://dl.dropboxusercontent.com/u/211279/loading3T.gif" alt="Loading"&gt;Uploading. Please wait...
    猜你喜欢
    • 2013-03-18
    • 1970-01-01
    • 2012-08-15
    • 2012-10-14
    • 2015-06-15
    • 2023-03-17
    • 1970-01-01
    • 2016-10-22
    • 2013-06-02
    相关资源
    最近更新 更多