【问题标题】:Google Apps Script: Downloading files from Drive (same user)Google Apps 脚本:从云端硬盘下载文件(同一用户)
【发布时间】:2017-08-14 07:21:16
【问题描述】:

我正在尝试编写一个 Google Apps 脚本来下载特定云端硬盘文件夹中的所有文件(可能是 .csv 文件)。我找到了 getDownloadUrl() 方法,但我无法弄清楚用它做什么。我目前正在尝试以下代码,其中files 是文件夹中的文件列表:

while(files.hasNext()) {
  var response = UrlFetchApp.fetch(files.next().getDownloadUrl());
  Logger.log(response.getContentText());
}

但是,当我尝试运行代码时,我收到 401 错误,我猜这意味着我缺乏适当的授权?但我的印象是,如果一切都发生在我的一个 Google 帐户中,我就不需要完成所有 OAuth2 步骤。 The Google guide to connecting to external APIs 看起来我应该能够获取网址。我已经可以访问我的云端硬盘文件,因为当我运行该方法时下载 URL 确实存在。我在这里想念什么?我对这一切都很陌生,所以也许这是一些基本的东西。

谢谢!

编辑: 我设法通过如下修改代码来修复 401 错误:

while(files.hasNext()) {
  var response = UrlFetchApp.fetch(files.next().getDownloadUrl(),{headers: {Authorization: "Bearer " + ScriptApp.getOAuthToken()}});
  Logger.log(response.getContentText());
}

但问题仍然存在,这只会将内容返回给我,而不是下载文件。如何从 fetch 调用的结果中启动下载?

【问题讨论】:

    标签: google-apps-script google-drive-api


    【解决方案1】:

    除了列出所有下载链接之外,我猜原发者还想将文件下载到用户的计算机(根据之前的discussion)。

    为此,请在服务器端使用 base 64 编码 blob(例如 Google App Script),并在客户端浏览器中使用数据 URI 下载。下面是这方面的代码,在 this answer 的帮助下。

    Google 应用脚本

    ...
    
    function getBlobInBase64(fileId){
      // omit authorization code if any
    
      var file = DriveApp.getFileById(fileId);
      var blob = file .getBlob();
      
      return {
        file_name: file.getName(),
        mime: file.getMimeType(),
        b64: Utilities.base64Encode(blob.getBytes());
    }
    
    ...
    

    使用index.html 服务的Javascript

    ...
    
    function getFile(fileId){
      google.script.run.withSuccessHandler((data) => {
    
        var uri = 'data:' + data.mime + ';charset=ISO-8859-1;base64,' + encodeURIComponent(data.b64);
        downloadURI(uri, data.file_name);
    
      }).withFailureHandler((err) => {
        console.log(err);
      }).getBlobInBase64();
    }
    
    ...
    

    注意:我还没有运行此代码,但该方法应该可以像在我的其他项目中使用的那样工作。

    【讨论】:

      【解决方案2】:

      这将记录任何可供下载的文件的文件名和 URL(根驱动器中的前 100 个):

      function myFunction() {
        var files = DriveApp.getFiles();
        var c = 0;
        while (files.hasNext() && c<100) {
          var file = files.next();
          Logger.log("File Name: " + file.getName());
          Logger.log("  Download URL: " + file.getDownloadUrl());
          c++;
        }
      }

      【讨论】:

      • 好的,但我已经可以获取下载网址了。我需要知道如何利用 URL 来使用 Apps Scripts 实际下载文件。它不会从日志文件中执行任何操作。我在网上找到的所有内容都意味着它应该只下载,但它没有。我是否需要先将其部署为网络应用程序?
      • 我最近确实编写了一个网络应用程序,它将在驱动器中搜索特定文件,然后返回带有文件链接的结果。我将分享它作为您可能尝试的答案。
      【解决方案3】:

      我的回答可能有点偏离,但我认为您有更好的机会从 Google Drive using the webContentLink 下载文件,因为这是我常用的方法。我通过使用Files.list 获取 webContentLink 并在 fields 参数中请求 webContentLink。我通过浏览器运行该链接并下载文件。

      【讨论】:

      • 我今天确实尝试在我的代码中使用该 URL,https://www.googleapis.com/drive/v3/files/FILE_ID?alt=media 之一。不幸的是它没有改变任何东西,但也许那是因为我试图在我的代码中运行它而不是通过在浏览器中输入它?使用 Google Scripts 听起来不可能,但我不确定
      【解决方案4】:

      如果您尝试使用 Google Apps 脚本将 Google Drive 文件下载到本地计算机,那么请了解 Google Apps 脚本是一种服务器端脚本语言。它无法将文件下载并保存到您的本地驱动器。

      【讨论】:

      • 这正是我想要的,所以这很不幸......但我认为我在网上找到了暗示我可以下载它们的东西,只是无法控制它们的下载位置(这取决于浏览器)。我知道很多网站都说你可以用 JavaScript 下载东西,是什么让 Google Script 与众不同?
      • 我认为@Anees 指的是谷歌文档,谷歌表格不可下载。但是 .pdf、.csv、jpg 等是可下载的。
      【解决方案5】:

      这是一个可能对您有所帮助的网络应用程序。它并不完全符合您的要求,但您可以对其进行编辑并获得结果。希望对您有所帮助!

      代码:

      function doGet(e) { // main function
        var template = HtmlService.createTemplateFromFile('index.html'); // filename always!
        return template.evaluate().setTitle('Search Drive').setSandboxMode(HtmlService.SandboxMode.IFRAME);
      }
      
      // Process the form
      function processForm(searchTerm) {
        var resultToReturn;
        Logger.log('processForm was called! ' + searchTerm);
        resultToReturn  = SearchFiles(searchTerm); // Call to the search files function to search files on google drive
        Logger.log('resultToReturn: ' + resultToReturn);
        return resultToReturn; // return the results
      }
      
      function SearchFiles(searchTerm) {
        var searchFor ="title contains '" + searchTerm + "'"; //single quotes are needed around searchterm
        var owneris ="and 'YOUREmail@email.com' in Owners"; //email address to search for 
        var names = [];
        Logger.log(searchFor + " " + owneris);
        var files = DriveApp.searchFiles(searchFor + " " + owneris); 
        while (files.hasNext()) {
          var file = files.next();
          var fileId = file.getId();// To get FileId of the file
          var lm = file.getLastUpdated();
          var name = file.getName()+"|~|"+fileId+"|~|"+lm; // Im concatenating the filename with file id separated by |~|
          names.push(name); // adding to the array
        }
        return names; // return results
      }

      索引.html

      <html>
        <head>
          <base target="_top">
          <script>
            function displayMessage() {
              var searchTerm;
              searchTerm = document.getElementById('idSrchTerm').value;
              console.log('searchTerm: ' + searchTerm );
              // Below call means: call to processForm passing the searchTerm value (previously escaped) and after finish call the handleResults function
               google.script.run.withSuccessHandler(handleResults).processForm(searchTerm.replace("'","\'")); 
             }
               
              
            function handleResults(results){
               console.log('Handle Results was called! ');
               document.writeln('<a href="http://LINKBACKTOYOURSCRIPT">BACK</a><br/><br/>');
               var length=results.length; // total elements of results
               for(var i=0;i<length;i++)
               {
               var item=results[i];
               item=item.split("|~|"); // split the line |~|, position 0 has the filename and 1 the file id
               
               document.writeln("<b><a href='https://docs.google.com/document/d/"+item[1]+"' target='_blank'>"+item[0]+"</b></a> (Last modified: "+item[2]+")<br/><br/>"); // write result
              
              }
              document.writeln("End of results...");
             }
      
      
          </script>
        </head>
        <body><center><br/>
          Search: <input type="text" id="idSrchTerm" name="search">
          <input type="button" value="search files on Google Drive" name="submitButton" onclick="displayMessage()"/>
      </center>
        </body>
      </html>

      【讨论】:

        猜你喜欢
        • 2017-07-13
        • 1970-01-01
        • 2017-09-21
        • 1970-01-01
        • 2017-08-10
        • 1970-01-01
        • 2016-08-09
        • 2016-09-04
        • 1970-01-01
        相关资源
        最近更新 更多