本文介绍了有没有办法使用 API 从谷歌驱动器上的多个文件创建一个 zip 文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您下载目录,Google Drive 网络界面允许您下载单个 .zip 文件.但是,我发现无法使用 API 做到这一点.是否可以使用 API 在驱动器上创建多文件 zip?

The Google Drive web interface allows you to download a single .zip file if you download a directory. However, I find no way to do that with the API. Is it possible to create a multi file zip on drive with the API?

更新:Tanakie 的代码有效!这很棒!但是,我只能在我的个人帐户中使用它.我有两个 G-Suite 管理员帐户,但出现错误:

Update: Tanakie's code works! This is great! However, I'm only able to get it working in my personal account. I have two G-Suite admin accounts and I get the error:

抱歉,目前无法打开文件.

"Sorry, unable to open the file at this time.

请检查地址,然后重试."

Please check the address and try again."

我已经确认这在多个免费的个人 Google 帐户中运行良好.知道为什么在使用付费谷歌帐户时它不起作用吗?

I have confirmed this works fine in multiple free personal google accounts.Any idea why it will not work when using a paid google account?

------- 更新 ------

------- UPDATE ------

如果您收到抱歉,此时无法打开文件"错误,请等待一天,该错误会自行修复.

If you get the "Sorry, unable to open the file at this time" error, wait a day, that error will fix itself.

这是我仅使用 POST 的最终解决方案.就像田池在下面所说的那样.

Here's my final solution only with a POST. Pretty much as Tanaike says below.

谷歌脚本:

function doPost(e) {
  var zipFileName = e.parameter.zipFileName
  var fileIds = e.parameter.ids.split(",");
  return ContentService.createTextOutput(zipping(fileIds, zipFileName));
}

function zipping(fileIds, zipfilename) {
  var blobs = [];
  var mimeInf = [];
  var accesstoken = ScriptApp.getOAuthToken();
  fileIds.forEach(function(fileID) {
      try {
          var file = DriveApp.getFileById(fileID);
          var mime = file.getMimeType();
          var name = file.getName();
      } catch (er) {
          return er
      }
      var blob;
      if (mime == "application/vnd.google-apps.script") {
          blob = UrlFetchApp.fetch("https://script.google.com/feeds/download/export?id=" + fileID + "&format=json", {
            method: "GET",
            headers: {"Authorization": "Bearer " + accesstoken},
            muteHttpExceptions: true
          }).getBlob().setName(name);
      } else if (~mime.indexOf('google-apps')) {
          mimeInf =
              mime == "application/vnd.google-apps.spreadsheet" ? ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", name + ".xlsx"] : mime == "application/vnd.google-apps.document" ? ["application/vnd.openxmlformats-officedocument.wordprocessingml.document", name + ".docx"] : mime == "application/vnd.google-apps.presentation" ? ["application/vnd.openxmlformats-officedocument.presentationml.presentation", name + ".pptx"] : ["application/pdf", name + ".pdf"];
          blob = UrlFetchApp.fetch("https://www.googleapis.com/drive/v3/files/" + fileID + "/export?mimeType=" + mimeInf[0], {
              method: "GET",
              headers: {"Authorization": "Bearer " + accesstoken},
              muteHttpExceptions: true
          }).getBlob().setName(mimeInf[1]);
      } else {
          blob = UrlFetchApp.fetch("https://www.googleapis.com/drive/v3/files/" + fileID + "?alt=media", {
              method: "GET",
              headers: {"Authorization": "Bearer " + accesstoken},
              muteHttpExceptions: true
          }).getBlob().setName(name);
      }
      blobs.push(blob);
  });
  var zip = Utilities.zip(blobs, zipfilename);
  var driveFolder = DriveApp.getFoldersByName("zipFiles").next();
  return driveFolder.createFile(zip).getId();
}

调用它的php代码:

$url       = 'https://script.google.com/a/domain.com/macros/s/### script id ####/exec';
$googleIDs = array();
foreach($documents AS $document){
    $googleIDs[] = $document->google_file_id;
}
$data['zipFileName'] = date('c') . ".zip";
$data['ids']         = join(',', $googleIDs);

$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array( "Content-type: multipart/form-data" ));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);

$result = curl_exec($ch); // This returns the Google file ID of the zip file.
curl_close($ch);

但是,正如我在下面的评论中一样,这是一个无用的、徒劳的练习,因为 Google 将脚本创建的文件限制为 10M.我要去寻找一个不依赖于 Google 的解决方案...希望我在开始之前就知道这一点.

HOWEVER, As in my comment below, this was a useless, futile exercise as Google limits files created by scripts to 10M. I'm off to find a solution that does not depend on Google... Wish I'd known that before I started.

推荐答案

这个解决方法怎么样?

很遗憾,Google API 中没有用于直接从外部创建 zip 文件的 API.但我认为有一个解决方法.Google Apps Script (GAS) 中有 Class Utilities 的 zip() 方法.并且有 Web 应用程序作为从外部使用 GAS 的服务.我认为你想做的事情可以通过结合它们来实现.

Unfortunately, there are no APIs for directly creating a zip file from outside in Google APIs. But I think that there is a workaround. There is zip() method of Class Utilities in Google Apps Script (GAS). And there is Web Apps as a service for using GAS from outside. I think that what you want to do can be achieved by combining them.

  1. 使用 Class Utilities 的 zip() 方法创建用于创建 zip 文件的 GAS 脚本.
  2. 将脚本部署为 Web 应用程序.
  3. 您可以使用应用程序的 GET 和 POST 方法从外部启动脚本.访问 Web Apps 时,也可以提供一些参数和数据.
  1. Create a GAS script for creating zip files using zip() method of Class Utilities.
  2. Deploy the script as Web Apps.
  3. You can launch the script from outside using GET and POST method of your applications. When you access Web Apps, also you can give some parameters and data.

参考:

  • 类实用程序中的 zip() 方法
  • 网络应用
  • 如果这对你没有用,我很抱歉.

    If this was not useful for you, I'm sorry.

    下面的示例脚本怎么样?这是一个简单的示例脚本,用于为文件夹中的文件创建 zip 文件.

    How about a following sample script? This is a simple sample script for creating a zip file for files in a folder.

    • 当电子表格、文档和幻灯片的 Google Docs 包含在文件夹中时,它们将分别转换为 Excel、Word 和 Powerpont 格式.
    • 当文件夹中包含独立脚本时,它们会转换为文本数据.
    • 其他类型(图片、文本数据等)不转换.

    这些与网页界面相同.

    请执行以下流程.

    1. 将示例脚本复制并粘贴到脚本编辑器中.并保存它.
    2. 部署网络应用
      • 在脚本编辑器上
        • 发布 -> 部署为网络应用
        • 在项目版本"中,创建新版本.
        • 在将应用执行为:"中,选择我".
        • 在谁有权访问该应用:"中,选择任何人,甚至是匿名的".
        • 点击部署按钮.
    • 如果能得到创建的zip文件的文件ID,说明脚本有效.

    示例脚本:

    function doGet(e) {
      var files = DriveApp.getFolderById(e.parameter.folderid).getFiles();
      var fileIds = [];
      while (files.hasNext()) {
        fileIds.push(files.next().getId());
      }
      return ContentService.createTextOutput(zipping(fileIds));
    }
    
    function zipping(fileIds) {
      var zipfilename = "sample.zip";
      var blobs = [];
      var mimeInf = [];
      var accesstoken = ScriptApp.getOAuthToken();
      fileIds.forEach(function(e) {
          try {
              var file = DriveApp.getFileById(e);
              var mime = file.getMimeType();
              var name = file.getName();
          } catch (er) {
              return er
          }
          var blob;
          if (mime == "application/vnd.google-apps.script") {
              blob = UrlFetchApp.fetch("https://script.google.com/feeds/download/export?id=" + e + "&format=json", {
                method: "GET",
                headers: {"Authorization": "Bearer " + accesstoken},
                muteHttpExceptions: true
              }).getBlob().setName(name);
          } else if (~mime.indexOf('google-apps')) {
              mimeInf =
                  mime == "application/vnd.google-apps.spreadsheet" ? ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", name + ".xlsx"] : mime == "application/vnd.google-apps.document" ? ["application/vnd.openxmlformats-officedocument.wordprocessingml.document", name + ".docx"] : mime == "application/vnd.google-apps.presentation" ? ["application/vnd.openxmlformats-officedocument.presentationml.presentation", name + ".pptx"] : ["application/pdf", name + ".pdf"];
              blob = UrlFetchApp.fetch("https://www.googleapis.com/drive/v3/files/" + e + "/export?mimeType=" + mimeInf[0], {
                  method: "GET",
                  headers: {"Authorization": "Bearer " + accesstoken},
                  muteHttpExceptions: true
              }).getBlob().setName(mimeInf[1]);
          } else {
              blob = UrlFetchApp.fetch("https://www.googleapis.com/drive/v3/files/" + e + "?alt=media", {
                  method: "GET",
                  headers: {"Authorization": "Bearer " + accesstoken},
                  muteHttpExceptions: true
              }).getBlob().setName(name);
          }
          blobs.push(blob);
      });
      var zip = Utilities.zip(blobs, zipfilename);
      return DriveApp.createFile(zip).getId();
    }
    

    curl 命令示例:

    curl -L "https://script.google.com/macros/s/#####/exec?folderid=### folder ID ###"
    

    注意:

    • 如果您修改了脚本,请将 Web 应用程序重新部署为新版本.这样就可以反映最新的脚本.
    • 作为示例脚本的限制,此示例脚本仅检查文件夹中的文件.如果要检索文件夹中的文件夹,可以查看示例脚本这里.
    • 得到创建的 ZIP 文件的文件 ID 后,就可以使用 Drive API 下载了.
    • 如果这对你有用,我很高兴.

      If this was useful for you, I'm glad.

      这篇关于有没有办法使用 API 从谷歌驱动器上的多个文件创建一个 zip 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-03 01:11