【问题标题】:Google Script - How to use unzip谷歌脚本 - 如何使用解压缩
【发布时间】:2020-12-30 21:49:50
【问题描述】:

我正在从网站下载 .zip。它包含一个 .txt 文件。我想访问 txt 中的数据并将其写入电子表格。我愿意直接访问它而不提取 zip 或提取 zip,将 txt 保存到 Google Drive 文件夹,并在保存后访问它。

当我使用Utilities.unzip() 时,我永远无法解压缩文件,并且通常会出现“无效参数”错误。在下面的代码中,else 之前的最后一段包含 unzip 命令。它成功地将文件保存到正确的 Google 文件夹,但我无法提取它。

function myFunction() {
  // define where to gather data from
  var url = '<insert url here>';
  var filename = "ReportUploadTesting05.zip";
  
  var response = UrlFetchApp.fetch(url, {
    // muteHttpExceptions: true,
    // validateHttpsCertificates: false,
    followRedirects: true  // Default is true anyway.
  });

  // get spreadsheet for follow up info
  var Sp = SpreadsheetApp.getActiveSpreadsheet();
  
  if (response.getResponseCode() === 200) {
    // get folder details of spreadsheet for saving future files
    var folderURL = getParentFolder(Sp);
    var folderID = getIdFromUrl(folderURL);
    var folder = DriveApp.getFolderById(folderID);
    
    // save zip file
    var blob = response.getBlob();
    var file = folder.createFile(blob);
    file.setName(filename);
    file.setDescription("Downloaded from " + url);
    var fileID = file.getId();
    Logger.log(fileID);
    Logger.log(blob)
    
    // extract zip (not working)
    file.setContent('application/zip')
    var fileUnzippedBlob = Utilities.unzip(file);  // invalid argument error occurs here
    var filename = 'unzipped file'
    var fileUnzipped = folder.createFile(fileUnzippedBlob)
    fileUnzipped.setName(filename)
  }
  else {
    Logger.log(response.getResponseCode());
  }
}

我已按照Utilities page 上的说明进行操作。我可以让他们的确切例子起作用。我尝试在我的计算机上创建一个 .zip,将其上传到 Google Drive 并尝试打开它,但没有成功。显然,使用我缺少的解压缩有一些微妙之处。

你能帮我理解一下吗?

【问题讨论】:

  • unzip 需要 Blob 类型,所以你可以尝试做Utilities.unzip(blob)
  • @Kos,谢谢,是的,我已经尝试过了,只是再次这样做是为了仔细检查。我抓住了我已经创建的blob 变量并将其放入Utilities.unzip。它会在同一行产生相同的错误消息。只是为了具体说明这一点,我读到文件是 blob 并且在其上调用 getBlob() 是多余的。
  • 通过我有限的测试,如果您跳过此代码file.setContent('application/zip') 并且根本不设置内容,该代码对我来说工作得很好。注意:我将压缩文件上传到谷歌驱动器并进行了测试!
  • 我看到您正在通过 createFile 存储 zip,您是否能够在应用程序脚本之外手动提取该 zip?也许问题出在保存步骤中。顺便说一句,我会在文件上调用 getBlob(),即使它是多余的(我不确定是不是),这是一个清晰的好主意。
  • 在同一张纸条上,我可以重现您的错误的唯一方法是当我给它非 zip 文件解压缩时。我认为您走在正确的轨道上,代码没有任何问题。相反,我认为这与 Utilities.unzip 无法识别压缩算法有关。为了测试相同,使用谷歌驱动器压缩软件压缩谷歌驱动器中的一堆文件,然后使用代码解压缩。它应该工作!

标签: google-apps-script unzip


【解决方案1】:

我在测试中遇到了同样的“无效参数”错误,所以不要使用:

file.setContent('application/zip')

我用过:

file.setContentTypeFromExtension();

而且,这为我解决了问题。此外,正如@tukusejssirs 所提到的,一个 zip 文件可以包含多个文件,因此 unzip() 返回一个 blob 数组(如文档所述 here)。这意味着您需要遍历文件,或者如果您知道只有一个文件,请显式引用它在数组中的位置,如下所示:

var fileUnzipped = folder.createFile(fileUnzippedBlob[0])

这是我的整个脚本,涵盖了这两个问题:

/**
 * Fetches a zip file from a URL, unzips it, then uploads a new file to the user's Drive.
 */
function uploadFile() {
  var url = '<url goes here>';
  var zip = UrlFetchApp.fetch('url').getBlob();

  zip.setContentTypeFromExtension();

  var unzippedFile = Utilities.unzip(zip);
  var filename = unzippedFile[0].getName();
  var contentType = unzippedFile[0].getContentType();
  var csv = unzippedFile[0];

  var file = {
    title: filename,
    mimeType: contentType
  };

  file = Drive.Files.insert(file, csv);
  Logger.log('ID: %s, File size (bytes): %s', file.id, file.fileSize);

  var fileId = file.id;

  // Move the file to a specific folder within Drive (Link: https://drive.google.com/drive/folders/<folderId>)
  var folderId = '<folderId>';
  var folder = DriveApp.getFolderById(folderId);
  var driveFile = DriveApp.getFileById(fileId);

  folder.addFile(driveFile);

}

【讨论】:

    【解决方案2】:

    我认为您的问题的答案可以在这里找到。 Is there a size limit to a blob for Utilities.unzip(blob) in Google Apps Script? 如果下载超过 100 mb,则无法下载完整文件。因此,它不会采用正确的 zip 格式。抛出无法解压文件错误。

    【讨论】:

      【解决方案3】:

      我相信从文件(在本例中为 .zip 文件)创建 blob 需要 .next();否则它对我不起作用。

      还要注意.zip 文件可能包含多个文件,因此我包含了一个for 循环。

      无论如何,我的工作/测试解决方案/脚本如下:

      function unzip(folderName, fileZipName){
        // Variables
        // var folderName = "folder_name";
        // var fileZipName = "file_name.zip";
        var folderId = getFolderId(folderName);
        var folder = DriveApp.getFolderById(folderId);
        var fileZip = folder.getFilesByName(fileZipName);
        var fileExtractedBlob, fileZipBlob, i;
      
        // Decompression
        fileZipBlob = fileZip.next().getBlob();
        fileZipBlob.setContentType("application/zip");
        fileExtractedBlob = Utilities.unzip(fileZipBlob);
        for (i=0; i < fileExtractedBlob.length; i++){
          folder.createFile(fileExtractedBlob[i]);
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-04-11
        • 1970-01-01
        • 2015-02-01
        • 2013-07-06
        • 1970-01-01
        相关资源
        最近更新 更多