将谷歌应用程序脚本移动到 v8 文件上传停止从侧边栏工作

Posted

技术标签:

【中文标题】将谷歌应用程序脚本移动到 v8 文件上传停止从侧边栏工作【英文标题】:Moving google apps script to v8 file upload stopped working from sidebar 【发布时间】:2020-06-29 17:35:52 【问题描述】:

我在 Google 电子表格中有一个 html 侧边栏,其中包含一个文件上传输入字段,该字段不适用于新的 v8 引擎。它确实在旧的 runtimeVersion DEPRECATED_ES5 中工作。

侧边栏中的文件上传用于将单个文件上传到我的谷歌驱动器。

HTML 文件

<body>
<h1>File Uploader</h1>
<form>
    <input type="file" name="myFile" id="file">
    <br>
    <input class="blue" type="button" id="submitBtn" value="Upload File" onclick="uploadthis(this.parentNode)">
    
</form>

<input type="button" value="Close" onclick="google.script.host.close()" />

<script>
  
function uploadthis(fileForm)

google.script.run
.uploadFiles(fileForm)



   
</script>
    
</body>

这里是简化的 gs

function uploadContract() 
  var html = HtmlService.createHtmlOutputFromFile('ContractUpload').setTitle('Kontrakt upload').setWidth(300);
SpreadsheetApp.getUi().showSidebar(html);


function uploadFiles(data)
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sStamdata = ss.getSheetByName('Stamdata_New');
var contractFolderId = sStamdata.getRange('D60').getValue(); 
var idag = Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd");
var title = sStamdata.getRange('D52').getValue();

var file = data.myFile;
var folder = DriveApp.getFolderById(contractFolderId);
var createFile = folder.createFile(file);
createFile.setName(idag+" - KONTRAKT - "+title);


【问题讨论】:

在我的测试中,google.script.run.uploadFiles(fileForm) 调用失败了。它甚至不调用该函数。它会引发一些“未捕获”的错误。我会在issuetracker.google.com/issues?q=componentid:191640 提交错误报告。提交时告诉我#,我会为它加星标,因为我看到了同样的问题。 事实上,我在developers.google.com/apps-script/guides/html/… 测试了谷歌自己的代码,除了在侧边栏中,它产生了同样的错误。谷歌的代码在一个普通的网络应用程序中工作。我想知道表单中的文件序列化是否仅适用于网络应用程序? 您的问题有什么我可以做的吗?如果我的回答对您的情况没有用。我必须道歉并修改它。如果您能合作解决您的问题,我很高兴。我想考虑一下解决方案。 @Tanaike 在我发布此消息后,由于 Covid-19,我们进入了锁定状态。所以我没有时间/可能性来测试它。但看起来你的答案将是一个很好的解决方法,我只是没有机会测试它。我也会尽快给你反馈。 @Kasper Egelund 感谢您的回复。我可以理解这种情况。也谢谢你。 【参考方案1】:

这个答案怎么样?请认为这只是几个可能的答案之一。

问题和解决方法:

我可以确认您问题的相同情况(这是在 Google 的Issue Tracker 上报告的)。在这种情况下,我认为启用 V8 后,当使用 google.script.run 将对象发送到 Google Apps 脚本端时,可能无法解析表单对象。虽然我认为这可能会在未来的更新中进行修改,但作为目前的解决方法,我建议将上传的文件作为字节数组发送到 GAS 端。

当你的脚本被修改后,变成如下。

修改后的脚本:

HTML&javascript 端:ContractUpload.html

请修改uploadthis如下。

function uploadthis(fileForm)
  const file = fileForm.myFile.files[0];
  const fr = new FileReader();
  fr.onload = function(e) 
    const obj = 
      // filename: file.name,  // In your script, the filename is given at GAS side. So I removed this.
      mimeType: file.type,
      bytes: [...new Int8Array(e.target.result)]
    ;
    google.script.run.withSuccessHandler((e) => console.log(e)).uploadFiles(obj);
  ;
  fr.readAsArrayBuffer(file);

Google Apps 脚本端:Code.gs

请修改uploadFiles如下。

function uploadFiles(data)
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sStamdata = ss.getSheetByName('Stamdata_New');
  var contractFolderId = sStamdata.getRange('D60').getValue(); 
  var idag = Utilities.formatDate(new Date(), "GMT+1", "yyyyMMdd");
  var title = sStamdata.getRange('D52').getValue();
  
  var file = Utilities.newBlob(data.bytes, data.mimeType, idag+" - KONTRAKT - "+title);  // Modified
  var folder = DriveApp.getFolderById(contractFolderId);
  var createFile = folder.createFile(file);
  return createFile.getId();  // Added

注意:

以上修改,文件上传时,将文件转换为字节数组发送到GAS端。然后,从字节数组创建文件。并返回文件 ID。您可以在控制台中看到它。

参考资料:

FileReader() newBlob(data, contentType, name)

如果我误解了您的问题并且这不是您想要的方向,我深表歉意。

【讨论】:

嗨,我试过这个workarround,但它不起作用...你能看看吗?谢谢。 ***.com/questions/61730044/… @Juan Bravo Roig 起初,在我的环境中,我可以确认这个脚本有效。我看到了你的问题。虽然在你的问题中,你说你上传了mp3,但当我在你的问题中看到console.log(file.mimeType)时,它是audio/wav。我认为上传 MP3 时,mimeType 是audio/mpeg。这个怎么样?顺便问一下it doesn't work...的详细情况吗?而且,你能提供完整的脚本来复制你的问题吗?如果可以,请将其添加到您的问题中。 感谢您的快速响应。日志是音频/wav,因为我已经使用 mp3 和 wav 文件进行了测试,但它们都不起作用。很抱歉造成误解。我的脚本和你的脚本之间的唯一区别是我传递了文件和几个表单字段。 file.bytes 和 file.mimeType 被正确发送到服务器函数,但是当我尝试创建 newBlob 时它只返回 undefined。 @Juan Bravo Roig 感谢您的回复。我测试了您添加的脚本。不幸的是,我可以确认脚本有效。当 blob 作为文件创建时,可以创建二进制文件(mp3 文件)。所以我无法复制你的问题。这是因为我的技术不好。我对此深表歉意。你能提供你当前的脚本来复制你的问题吗? 嗨!我终于解决了这个问题,这真的很荒谬。我已经更新了问题并添加了回复。也谢谢!

以上是关于将谷歌应用程序脚本移动到 v8 文件上传停止从侧边栏工作的主要内容,如果未能解决你的问题,请参考以下文章

复制谷歌应用脚本文件,使用... 谷歌应用脚本到teamDrive中。

将谷歌表格中的特定范围插入到 MYSQL

如何将谷歌地图添加到android

如何将谷歌视觉 API 响应保存到可处理的文件中

如何使用谷歌应用脚​​本将视频从谷歌驱动器上传到 YouTube?

将谷歌驱动器选择器文件转换为 javascript 文件类型