每次进行编辑时,都会将Google电子表格导出为.XLSX

时间:2013-10-16 08:44:17

标签: google-apps-script google-sheets export-to-excel

我想要一个Google脚本,只要进行编辑,就会自动将电子表格导出到.XLSX,覆盖以前的任何版本。使用this answer作为模板,我创建了以下代码:

function onEdit() {
  var s = SpreadsheetApp.getActiveSheet();
  var r = s.getActiveCell();
  if( r.getColumn() != 1 ) { //checks the column
    var row = r.getRow();
    var time = new Date();
    time = Utilities.formatDate(time, "GMT-08:00 ", "MM/dd/yy, hh:mm:ss");
    SpreadsheetApp.getActiveSheet().getRange('A' + row.toString()).setValue(time); 

    var id = 'MY_SPREADSHEET_KEY'
    var url = 'https://docs.google.com/feeds/';
    var doc = UrlFetchApp.fetch(url+'download/spreadsheets/Export?key='+id+'&exportFormat=xls',
                                googleOAuth_('docs',url)).getBlob()
    DocsList.createFile(doc).rename('newfile.xls')
  };
 };

function googleOAuth_(name,scope) {
  var oAuthConfig = UrlFetchApp.addOAuthService(name);
  oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
  oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
  oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
  oAuthConfig.setConsumerKey('anonymous');
  oAuthConfig.setConsumerSecret('anonymous');
  return {oAuthServiceName:name, oAuthUseToken:"always"};
}

然而,它似乎并不是出口。或者,如果是出口,我不确定这是怎么回事。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

由于Google的API发生变化,Serge的某些脚本已无法使用,我发布的脚本基本上将当前的电子表格导出到xlsx(请注意导出到xls不受支持)并将其保存到名为Exports的文件夹中。在执行此操作之前,它会删除以前的xlsx文件并仅保留最新文件,这样您就不需要计算时间或更改任何单元格:

function exportAsxlsx() {
  var spreadsheet   = SpreadsheetApp.getActiveSpreadsheet();
  var spreadsheetId = spreadsheet.getId()
  var file          = Drive.Files.get(spreadsheetId);
  var url           = file.exportLinks[MimeType.MICROSOFT_EXCEL];
  var token         = ScriptApp.getOAuthToken();
  var response      = UrlFetchApp.fetch(url, {
    headers: {
      'Authorization': 'Bearer ' +  token
    }
  });

  var blobs   = response.getBlob();
  var folder = DriveApp.getFoldersByName('Exports');
  if(folder.hasNext()) {
    var existingPlan1 = DriveApp.getFilesByName('newfile.xlsx');
    if(existingPlan1.hasNext()){
      var existingPlan2 = existingPlan1.next();
      var existingPlanID = existingPlan2.getId();
      Drive.Files.remove(existingPlanID);
    }
  } else {
    folder = DriveApp.createFolder('Exports');
  }
  folder = DriveApp.getFoldersByName('Exports').next();
  folder.createFile(blobs).setName('newfile.xlsx')
}

如果没有特定文件夹,它还会创建特定文件夹。您可以使用这些命令并查看这些类的工作方式。请注意,您需要从Resources -> Advanced Google Services -> Drive API启用Drive API,方法是将其切换为on,也可以从Google Developers Console启用(请参阅详细说明here)。我还设置了一个简单的触发器,在每次编辑时调用此函数。这可以通过以下方式完成:Resources -> Current project's triggers -> Add a new trigger。您不需要添加任何库。

答案 1 :(得分:2)

事实并非如此!可能是因为oAuth函数没有得到正确的授权,而且还because the simple onEdit is not allowed进行了这种操作。

您必须创建可安装触发器menu>ressource>current trigger>create)。

请尝试以下此脚本并运行authorize功能。

我还更改了一些详细信息:timeZone直接来自电子表格,id也来自活动电子表格。

另请注意,新创建的XLSX不会覆盖任何以前的文件,您将获得许多具有相同名称的文档!如果您只想保留最新版本,那么您应该自己处理,获取所有文档名称的“新文件”,然后在创建新文件之前使用file.setTrashed(true)将其删除。

这就像这两行代码一样简单:

var oldVersions = DocsList.find('newfile.xls');
for(var d in oldVersions){oldVersions[d].setTrashed(true)};

代码:

function myOnEdit() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getActiveSheet();
  var r = s.getActiveCell();
  if( r.getColumn() != 1 ) { //checks the column
    var row = r.getRow();
    var time = new Date();
    time = Utilities.formatDate(time, ss.getSpreadsheetTimeZone(), "MM/dd/yy, hh:mm:ss");
    var id = ss.getId();
    s.getRange('A' + row.toString()).setValue(time); 
    var url = 'https://docs.google.com/feeds/';
    var doc = UrlFetchApp.fetch(url+'download/spreadsheets/Export?key='+id+'&exportFormat=xls',
                                googleOAuth_('docs',url)).getBlob()
    DocsList.createFile(doc).rename('newfile.xls')  
  }
}

function authorise(){
  // function to call to authorize googleOauth
  var id=SpreadsheetApp.getActiveSpreadsheet().getId();
  var url = 'https://docs.google.com/feeds/';
  var doc = UrlFetchApp.fetch(url+'download/spreadsheets/Export?key='+id+'&exportFormat=xls',
                            googleOAuth_('docs',url)).getBlob()
}
function googleOAuth_(name,scope) {
  var oAuthConfig = UrlFetchApp.addOAuthService(name);
  oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
  oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
  oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
  oAuthConfig.setConsumerKey('anonymous');
  oAuthConfig.setConsumerSecret('anonymous');
  return {oAuthServiceName:name, oAuthUseToken:"always"};
}

编辑:在您的评论之后,这是一个仅每30秒保存一次的版本(如果不进行编辑则更多)。如有必要,您可以轻松地将时间值更改为另一个时间间隔。

重新运行authorize函数以初始化scriptProperty。

function myOnEdit() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = ss.getActiveSheet();
  var r = s.getActiveCell();
  if( r.getColumn() != 1 ) { //checks the column
    var row = r.getRow();
    var time = new Date();
    time = Utilities.formatDate(time, ss.getSpreadsheetTimeZone(), "MM/dd/yy, hh:mm:ss");
    var id = ss.getId();
    s.getRange('A' + row.toString()).setValue(time); 
    var lastSaveTime = new Date(Utilities.jsonParse(ScriptProperties.getProperty('exportTime')));
    var now = new Date().getTime();
    Logger.log(now - lastSaveTime.getTime())
    if (now - lastSaveTime.getTime() > 60000){ // delete every minute
      var oldVersions = DocsList.find('newfile.xls');
      for(var d in oldVersions){oldVersions[d].setTrashed(true)};
    }
    if (now - lastSaveTime.getTime() > 30000){ // save every 30"
      var url = 'https://docs.google.com/feeds/';
      var doc = UrlFetchApp.fetch(url+'download/spreadsheets/Export?key='+id+'&exportFormat=xls',
                                  googleOAuth_('docs',url)).getBlob()
      DocsList.createFile(doc).rename('newfile.xls')  
      ScriptProperties.setProperty('exportTime',Utilities.jsonStringify(new Date()));
    }
  }
}

function authorise(){
  // function to call to authorize googleOauth + initialize the TIMER
  ScriptProperties.setProperty('exportTime',Utilities.jsonStringify(new Date()));
  var id = SpreadsheetApp.getActiveSpreadsheet().getId();
  var url = 'https://docs.google.com/feeds/';
  var doc = UrlFetchApp.fetch(url+'download/spreadsheets/Export?key='+id+'&exportFormat=xls',
                                googleOAuth_('docs',url)).getBlob()
}

function googleOAuth_(name,scope) {
  var oAuthConfig = UrlFetchApp.addOAuthService(name);
  oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
  oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
  oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
  oAuthConfig.setConsumerKey('anonymous');
  oAuthConfig.setConsumerSecret('anonymous');
  return {oAuthServiceName:name, oAuthUseToken:"always"};
}