Google Apps脚本会创建Excel文件的工作表版本

时间:2018-03-13 01:24:34

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

我正在努力实现流程自动化。目前,我正在将Excel(.xlsx)文件上传到云端硬盘中的特定文件夹。然后我手动将它们转换为Google Sheet文件,并将其移动到单独的文件夹中。我想自动化这个过程。我知道我必须编写脚本来迭代2个文件夹来比较并查看哪些文件尚未转换,然后转换它们在两个位置都找不到的文件。但是,我正在努力实现这一目标的最佳方法。

下面的代码可能会或可能不会出现在正确的轨道上,我对此非常陌生并且真的只是尝试将它拼凑在一起。任何人的见解都将受到高度赞赏。

function Excel2Sheets() 
{

  //Logs excel folder and string of files within
  var excelfolder = DriveApp.getFolderById('1JbamZxNhAyZT3OifrIstZKyFF_d257mq');
  var excelfiles = excelfolder.getFiles();

  // Logs sheets folder and string of files within
  var sheetfolder = DriveApp.getFolderById('1y10IwMobCdpQlYwWdveHLzxEz3Xml0Qt');
  var ID = sheetfolder.getId();
  var sheetfiles = sheetfolder.getFiles();
  var MType = MimeType.GOOGLE_SHEETS;

  while (excelfiles.hasNext()) {
    var excelfile = excelfiles.next();
    var excelname = excelfile.getName();

    while (sheetfiles.hasNext()) {
      var sheetfile = sheetfiles.next();
      var sheetname = sheetfile.getName();

      if(sheetname == excelname) {
        break;
      }
      if(sheetfiles.hasNext(0)) {
        var blob = excelfile.getBlob();
        sheetfolder.createFile(excelname, blob, MType);
        break;
      }
    }
  }
}

我也玩过这段代码。感谢

function fileChecker()
{
  try{
    //Establishes Excel Source Folder
    var excelfolder = DriveApp.getFolderById('1JbamZxNhAyZT3OifrIstZKyFF_d257mq');
    //Establishes Sheet Target Folder
    var sheetfolder = DriveApp.getFolderById('1y10IwMobCdpQlYwWdveHLzxEz3Xml0Qt');
    //Establishes Return File Type
    var MType = MimeType.GOOGLE_SHEETS;
    //Gets all files in excel folder
    var excelfiles = excelfolder.getFiles();

    //loop through excel files
    while(excelfiles.hasNext()){
      //Establishes specific excel file  
      var excelfile = excelfiles.next();
      //Checks for file with same name in sheets folder
      var sheetfiles = sheetfolder.getFilesByName(excelfile.getName());
      //Logical Test for file match
      if(sheetfiles.hasNext()){
        //Gets File Name
        var excelname = excelfile.getName();
        //Creates File Blob
        var blob = excelfile.getBlob();  
        // Creates sheet file with given name and data of excel file
        sheetfolder.createFile(excelname, blob, MType);
      }
    } 
  }
  catch(err){
    Logger.log(err.lineNumber + ' - ' + err);
  }
}

1 个答案:

答案 0 :(得分:1)

您的任何一个代码,如果要到达createFile行,都应该抛出此错误:

  

无效参数:file.contentType

因为您在createFile(name, content, mimetype) expects a String时传递Blob

查看DriveApp的参考页面,毫无疑问会注意到返回Blob的File#getAs(mimetype)方法和Folder#createFile(blob)方法,并尝试以下方法:

var gsBlob = excelfile.getAs(MimeType.GOOGLE_SHEETS);
gsfolder.createFile(gsBlob).setName(excelfile.getName());

然而,这也会返回错误:

  

从application / vnd.openxmlformats-officedocument.spreadsheetml.sheet转换              不支持application / vnd.google-apps.spreadsheet。

查看getAs方法的文档表明,除非目标mimetype为MimeType.PDF,否则这通常是不受支持的操作。我猜这是因为PDF转换很简单 - 它的实现可能使用类似“打印”的功能 - 而电子表格格式转换需要仔细处理公式,图像,图表等。

根据过去使用Google云端硬盘的经验,一般用户都知道能够使用云端硬盘执行Excel的自动转换 - > Google表格存在。但是,此功能仅在上载期间可用。从closely related question绘制,我们发现必须使用Drive API“高级服务”,而不是更简单的原生DriveApp。启用Advanced Service,然后以下代码段即可运行。请注意,高级驱动器服务将文件夹视为具有特定mimetype的文件(这就是没有特定于文件夹的方法的原因),因此对于Apps脚本环境中的用户来说,同时使用DriveApp和高级服务最为简单​​。

// Convert the user's stored excel files to google spreadsheets based on the specified directories.
// There are quota limits on the maximum conversions per day: consumer @gmail = 250.
function convertExcelToGoogleSheets() 
{
  var user = Session.getActiveUser(); // Used for ownership testing.
  var origin = DriveApp.getFolderById("origin folder id");
  var dest = DriveApp.getFolderById("destination folder id");

  // Index the filenames of owned Google Sheets files as object keys (which are hashed).
  // This avoids needing to search and do multiple string comparisons.
  // It takes around 100-200 ms per iteration to advance the iterator, check if the file
  // should be cached, and insert the key-value pair. Depending on the magnitude of
  // the task, this may need to be done separately, and loaded from a storage device instead.
  // Note that there are quota limits on queries per second - 1000 per 100 sec:
  // If the sequence is too large and the loop too fast, Utilities.sleep() usage will be needed.
  var gsi = dest.getFilesByType(MimeType.GOOGLE_SHEETS), gsNames = {};
  while (gsi.hasNext())
  {
    var file = gsi.next();
    if(file.getOwner().getEmail() == user.getEmail())
      gsNames[file.getName()] = true;
  }

  // Find and convert any unconverted .xls, .xlsx files in the given directories.
  var exceltypes = [MimeType.MICROSOFT_EXCEL, MimeType.MICROSOFT_EXCEL_LEGACY];
  for(var mt = 0; mt < exceltypes.length; ++mt)
  {
    var efi = origin.getFilesByType(exceltypes[mt]);
    while (efi.hasNext())
    {
      var file = efi.next();
      // Perform conversions only for owned files that don't have owned gs equivalents.
      // If an excel file does not have gs file with the same name, gsNames[ ... ] will be undefined, and !undefined -> true
      // If an excel file does have a gs file with the same name, gsNames[ ... ] will be true, and !true -> false
      if(file.getOwner().getEmail() == user.getEmail() && !gsNames[file.getName()])
      {
        Drive.Files.insert(
          {title: file.getName(), parents: [{"id": dest.getId()}]},
          file.getBlob(),
          {convert: true}
        );
        // Do not convert any more spreadsheets with this same name.
        gsNames[file.getName()] = true;
      }
    }
  }
}

我上面的代码强制要求您关心的文件是您拥有的文件。如果情况并非如此,则建议删除电子邮件检查。请注意在一天内转换过多的电子表格。

如果使用“应用脚本”中的Advanced Service,则查看相关API的Google API客户端库文档通常很有帮助,因为没有特定的Apps脚本文档。我个人觉得Python equivalent最容易使用。