【问题标题】:Google app script: upload a csv file from html serviceGoogle 应用脚本:从 html 服务上传 csv 文件
【发布时间】:2020-02-26 14:50:53
【问题描述】:

我正在尝试从 google 表格中的 html 服务上传 csv 文件,经过一番研究,我发现了一些当时似乎可以工作的代码:

html服务调用

function importAnalysis() {
  var html = HtmlService.createHtmlOutputFromFile('Import')
      .setWidth(1524)
      .setHeight(800);
  SpreadsheetApp.getUi()
      .showModalDialog(html, 'Import d\'analyse');
}

html 模板

<!DOCTYPE html>
  <html>
    <body>
      <form>
        <input type="file" name="analysisCsv" accept=".csv">
        <input type="button" onclick="google.script.run.processForm(this.parentNode);">
      </form>
    </body>
  </html>

gs 文件(我注释了更多代码以隔离问题的根源):

function processForm(form) {
  let fileBlob=form.analysisCsv;
//  sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Table_Analysis");
//  let lastRow = sheet.getLastRow();
//  let values = []
//  let rows = fileBlob.contents.split('\n');
//  for(let r=0; r<rows.length; ++r){
//    values.push( rows[r].split(';') );
//  }
//  for (var i = 0; i < values.length; i++) {
//    sheet.getRange(lastRow+i+1, 1, 1, values[i].length).setValues(new Array(values[i]));
//  }  
}

问题是我在 processForm 函数上收到错误 400: "加载资源失败:服务器响应状态为 400()"

您知道我的代码有什么问题,或者以其他方式在我的工作表中上传 csv 内容吗?

【问题讨论】:

  • 您可以尝试将函数名称重命名为 receiveForm 之类的名称吗?
  • 尝试使用类似 google.script.run.proccessForm(this.parentNode)
  • 能否请您尝试使用 Apps Script 的 STABLE 版本而不是 V8,以防万一出现问题,让我知道它是如何解决的?要实现这一点,请按照以下步骤操作:Open the Script Editor. In the top menu, select View &gt; Show manifest file. In the files list, open appsscript.json. Replace "runtimeVersion": "V8" with "runtimeVersion": "STABLE" Save.
  • 当我将 "V8" 更改为 "STABLE" 时,我收到一个错误 "Missing ; sign before instruction" 并且我无法跟踪它的来源,html 根本不显示。

标签: forms google-apps-script file-upload


【解决方案1】:

所以总结一下,我不得不强制 Legacy 运行时: 选择运行 > 禁用由 V8 提供支持的新 Apps 脚本运行时。 然后编辑所有 V8 语法:主要将“let”替换为“var”。 现在它正在工作,谢谢大家。

https://developers.google.com/apps-script/guides/v8-runtime/migration https://developers.google.com/apps-script/guides/v8-runtime#enabling_the_v8_runtime

【讨论】:

    【解决方案2】:

    您不能为 doPost() 提供参数。来自文档:

    When a user visits an app or a program sends the app an HTTP GET request, Apps Script runs the function doGet(e). When a program sends the app an HTTP POST request, Apps Script runs doPost(e) instead. In both cases, the e argument represents an event parameter that can contain information about any request parameters. The structure of the event object is shown in the table below: 还有here's a link to that

    正如我在上面的评论中所说,将表单传递给服务器的一种简单方法是:

    google.script.run.proccessForm(this.parentNode)

    这在here和部分here进行了解释

    好吧,我终于自己运行了您的代码,果然它在 V8 中不起作用。

    所以我移到旧版本,这是我使用的代码:

    GS:

    function runThree() {
      var html = HtmlService.createHtmlOutputFromFile('ah3').setWidth(400).setHeight(400);
      SpreadsheetApp.getUi().showModelessDialog(html, 'Title');
    }
    
    function processForm(form) {
      Logger.log(JSON.stringify(form));
      var fileBlob=form.analysisCsv;
      var folder=DriveApp.getFolderById(getGlobal('TestFolderId'));
      var file=folder.createFile(fileBlob);
      var csv=Utilities.parseCsv(file.getBlob().getDataAsString());
      var sh=SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet10");
      var rg=sh.getRange(sh.getLastRow()+1,1,csv.length,csv[0].length).setValues(csv);
      return "I've got it";
    }
    

    HTML:

    <!DOCTYPE html>
      <html>
        <head>
        <base target="_top">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
        </head>
        <body>
          <form>
            <input type="file" name="analysisCsv" accept=".csv">
            <input type="button" value="Save" onclick="intermediate(this.parentNode);">
            <div id="msg"></div>
          </form>
          <script>
            function intermediate(obj) {
              google.script.run
              .withSuccessHandler(function(msg){$('#msg').html(msg);google.script.host.close();})
              .processForm(obj);
            }
            console.log('My Code');
          </script>
        </body>
      </html>
    

    我刚刚创建了一个 csv 文件并上传到一个文件夹,然后使用 Utilites.parseCsv() 将其转换为可以使用 setValues() 插入电子表格的二维数组;

    【讨论】:

    • 谢谢,我改了函数名,但错误仍然存​​在。
    • 这里有一个例子你可以看看:stackoverflow.com/a/57581534/7215091
    • 基本上是一样的代码,只是在脚本中调用了服务器函数而不是正文。我试过了,但仍然出现同样的错误。
    • 只是好奇,你为什么要注释掉你的代码?
    • 我只是想确定错误不是由进一步的代码引起的,但它发生在第 1 行(函数调用)。
    【解决方案3】:

    这是我使用客户端FileReader API的解决方案:

    code.gs:

    function doSomething(csvstr) {
      Logger.log('doSomething', csvstr);
    
      const csvarr = Utilities.parseCsv(csvstr);
    
      return csvarr; // now an array !
    }
    

    index.html:

    <!DOCTYPE html>
    <html>
      <head>
        <base target="_top">
    
      </head>
      <body>
        <input type="file">
    
        <script>
        const $input = document.querySelector('input')
    
        $input.onchange = function (e) {
          // File
          const file = e.target.files[0]
    
          //
          // FileReader
          //
          // see: https://web.dev/read-files/#read-content
          //
    
          const reader = new FileReader();
    
          reader.onerror = event => {
            console.error('error while reading CSV file', event)
            reader.abort()
          }
    
          reader.onload = event => {
            const content = event.target.result // result
            console.log(content)
    
            // https://developers.google.com/apps-script/guides/html/reference/run
            google.script.run
              .withFailureHandler(err => {
                console.error('oh noes', err)
              })
              .withSuccessHandler(val => {
                console.log('yay!', val)
    
                google.script.host.close() // https://developers.google.com/apps-script/guides/html/reference/host#close
              })
              .doSomething(content)
          }
          reader.readAsText(file);
        }
        </script>
      </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-06
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-27
      • 2023-03-23
      相关资源
      最近更新 更多