【问题标题】:Is there a way to create a zip file from multiple files on google drive with the API?有没有办法使用 API 从谷歌驱动器上的多个文件创建一个 zip 文件?
【发布时间】:2018-04-05 17:09:06
【问题描述】:

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

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

“抱歉,目前无法打开文件。

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

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

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

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

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

谷歌脚本:

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 的解决方案...希望我在开始之前就知道这一点。

【问题讨论】:

  • 当心!!!我确实得到了这个工作。但是,由于 Google 将脚本创建的文件限制为 10M,因此几乎没有用处。
  • 给您带来的不便,我深表歉意。我应该首先询问您使用的尺寸。我很抱歉。
  • 我能问你一个文件的大小吗?如果小于 10MB,那么以 10MB 为单位创建 zip 文件怎么样?
  • 一组文件很容易达到数百兆。有些更大。拆分成 10M 的文件是不切实际的。大多数单个文件都小于 10M,但在这种情况下,用户无需压缩即可下载该文件。我正在处理大量数据。
  • 感谢您提供的信息。给您带来的不便,我深表歉意。

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


【解决方案1】:

这个解决方法怎么样?

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

流程:

  1. 使用 Class Utilities 的 zip() 方法创建 GAS 脚本以创建 zip 文件。
  2. 将脚本部署为 Web 应用程序。
  3. 您可以使用应用程序的 GET 和 POST 方法从外部启动脚本。访问 Web Apps 时,也可以提供一些参数和数据。

参考:

如果这对你没有用,我很抱歉。

编辑:

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

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

这些与网页界面相同。

为了使用这个脚本

请执行以下流程。

  1. 将示例脚本复制并粘贴到脚本编辑器中。并保存它。
  2. 部署 Web 应用程序
    • 在脚本编辑器上
      • 发布 -> 部署为网络应用
      • 在“项目版本”中,创建新版本。
      • 在“将应用程序执行为:”中,选择“我”。
      • 在“谁有权访问应用程序:”中,选择“任何人,甚至匿名”。
      • 点击部署按钮。
  3. 使用 curl 命令测试 Web 应用程序,如下所示。
    • 如果可以得到创建的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 应用程序重新部署为新版本。这样就可以反映最新的脚本。
  • 作为示例脚本的限制,此示例脚本仅检查文件夹中的文件。如果要检索文件夹中的文件夹,可以看示例脚本here
  • 得到创建的 ZIP 文件的文件 ID 后,就可以使用 Drive API 下载了。

如果这对你有用,我很高兴。

【讨论】:

  • 这是个好主意!我还需要一段时间才能尝试,但如果我能让它发挥作用,我会回来接受这个答案。谢谢!
  • @Tim Duncklee 欢迎您。谢谢你的cmets。如果您需要示例脚本,请随时告诉我。
  • 如果您不介意,一个示例脚本会很棒!谢谢!
  • @Tim Duncklee 我更新了我的答案。请确认。
  • @Tim Duncklee 如果这对你没有用,我很抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
  • 2023-01-20
  • 2020-09-03
  • 1970-01-01
  • 2014-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多