从Google电子表格行

时间:2016-09-02 18:04:16

标签: google-apps-script google-sheets

我正在使用此处找到的代码: How to convert a Google Docs-File to an Excel-File (XLSX),更具体地说是in this gist来创建Excel文件。

我需要修改代码。

  1. 每次向Google添加新行时创建一个Excel文件 电子表格。 立即工作
  2. 新的Excel文件第1行应该是源电子表格中的标题,第2行应该是添加到 来源电子表格。
  3. 文件的名称应基于新行中的值,第2列和第2列。 15. 立即工作
  4. 新的Excel文件应放在“Form Responses”文件夹中id = 0B-eAmBjlnU16YTJIVVFpMjJoTzQ。 立即工作
  5. 我能够修改代码以在添加新行时触发,以使用最后一行的值,第2列和第2列。 15作为文件的名称,并将新创建的文件移动到特定的文件夹(步骤1,3和4),但我停留在第2步。该功能在手动运行时不起作用,当我期望它时(在电子表格更改,编辑或表单提交)

          function test_downloadXLS() {
      var fileId = SpreadsheetApp.openById("ID").getId();
      downloadXLS( fileId);
      var range = SpreadsheetApp.getActiveSheet().getRange('A2:DI2');
    
      var files = DriveApp.getRootFolder().getFiles();
      while (files.hasNext()) {
        var file = files.next();
        var destination = DriveApp.getFolderById("0B-eAmBjlnU16YTJIVVFpMjJoTzQ");
        destination.addFile(file);
        var pull = DriveApp.getRootFolder();
        pull.removeFile(file);
        range.clear()
      }
     }
    
    /**
     * Downloads spreadsheet with given file id as an Excel file.
     * Uses Advanced Drive Service, which must be enabled.
     * Throws if error encountered.
     *
     * From https://stackoverflow.com/a/27281729/1677912
     *
     * @param {String}   fileId       File ID of Sheets file on Drive.
     */
    function downloadXLS(fileId) {
      var file = Drive.Files.get(fileId);
      var url = file.exportLinks[MimeType.MICROSOFT_EXCEL];
    
     var options = {
       headers: {
         Authorization:"Bearer "+ScriptApp.getOAuthToken()
       },
        muteHttpExceptions : true        /// Get failure results
      }
    
      var response = UrlFetchApp.fetch(url, options);
      var status = response.getResponseCode();
      var result = response.getContentText();
      if (status != 200) {
        // Get additional error message info, depending on format
        if (result.toUpperCase().indexOf("<HTML") !== -1) {
          var message = strip_tags(result);
        }
        else if (result.indexOf('errors') != -1) {
          message = JSON.parse(result).error.message;
        }
        throw new Error('Error (' + status + ") " + message );
      }
    
      var ss = SpreadsheetApp.openById('16Vv_FqrZyeCmCoK9XAvujVRisa-5m3FabH5uNAKprYc');
      var sh = ss.getSheets()[0];// access first sheet (0 indexed)
      var row = sh.getLastRow();
      var data = sh.getRange(row, 2).getValue();
       var row2 = sh.getLastRow();
      var data2 = sh.getRange(row, 15).getValue();
    
      var doc = response.getBlob();
      DriveApp.createFile(doc).setName(data + "-" + data2 + '.xlsx');
    }
    
    
    // A JavaScript equivalent of PHP’s strip_tags
    // from http://phpjs.org/functions/strip_tags/
    function strip_tags(input, allowed) {
      allowed = (((allowed || '') + '')
        .toLowerCase()
        .match(/<[a-z][a-z0-9]*>/g) || [])
        .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
      var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
        commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
      return input.replace(commentsAndPhpTags, '')
        .replace(tags, function($0, $1) {
          return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
        });
    } 
    

    我没有太多运气找到有关如何仅将特定范围导出为ex​​cel文件的信息(步骤2),所以我尝试了一种不同的方法但取得了一些成功但遇到了另一个问题。

    我创建了第二个电子表格,其标题与第一个相同。在第一个电子表格中,我使用以下代码将新行复制到此新电子表格中:

      function initializeTrigger()
      var sheet = SpreadsheetApp.getActive();
     ScriptApp.newTrigger("myFunction")
       .forSpreadsheet(sheet)
       .onChange()
       .create();
    }
    function myFunction(e){
      Logger.log(e.changeType);
      if(e.changeType=='INSERT_ROW'){
      var ss = SpreadsheetApp.openById('ID');
      var ssd = SpreadsheetApp.openById('ID');
      var sourceSheet = ss.getSheetByName('Responses');
      var lastrow = sourceSheet.getLastRow();
      var sourceData = sourceSheet.getRange(lastrow, 1, 1, 53).getValues();
    ssd.appendRow(sourceData[0]);
    }
    } 
    

    在新的电子表格中,第二个,我尝试了在这篇文章开头看到的原始代码,但它不起作用。我认为这里的问题可能是我正在添加一行,导出它然后删除该行,以便下次在日志上复制新行时没有看到新行的新内容?

    我还尝试了这里引用的代码in this gist,它在手动运行时有效,但我无法找到一个触发器,只要复制新行就会有效。

1 个答案:

答案 0 :(得分:0)

所以我所要做的就是将所有代码放入一个脚本文件中,以便一次性触发。可能不是最有效或最漂亮的方式,但它适用于我需要它做的事情。一个问题是如果同时添加新行,则excel文件的命名和创建将存在问题。

要点: 该脚本将执行以下操作

  1. 仅将新行从一个电子表格移动到第二个电子表格 头
  2. 根据第二个电子表格
  3. 创建一个Excel文件
  4. 将excel文件移至特定文件夹
  5. 删除在第二个电子表格中创建的行,以预期下一个新行
  6. 首先运行initializeTrigger。触发器应设置为“on change”。

    function initializeTrigger(){ // run this only once to create a trigger if necessary
      var sheet = SpreadsheetApp.getActive();
      ScriptApp.newTrigger("myFunction")
      .forSpreadsheet(sheet)
      .onChange()
      .create();
    }
    
    function myFunction(e){
      Logger.log(e.changeType);
      if(e.changeType=='INSERT_ROW'){ // do Something
    
      var ss = SpreadsheetApp.openById('Spreadsheet ID'); //Project database and source data sheet #1
      var ssd = SpreadsheetApp.openById('Spreadsheet ID'); //Spreadsheet to be converted into excel document
      var sourceSheet = ss.getSheetByName('Responses'); 
      var lastrow = sourceSheet.getLastRow();
      var sourceData = sourceSheet.getRange(lastrow, 1, 1, 113).getValues();
      ssd.appendRow(sourceData[0]);
      var fileId = SpreadsheetApp.openById("Spreadsheet ID").getId(); //Spreadsheet to be converted into excel document
      downloadXLS( fileId);
      var files = DriveApp.getRootFolder().getFiles();
      while (files.hasNext()) {
        var file = files.next();
        var destination = DriveApp.getFolderById("Folder ID"); // Folder where exported excel files are moved too
        destination.addFile(file);
        var pull = DriveApp.getRootFolder();
        pull.removeFile(file);
        ssd.deleteRow(2)
    }
    }
    
     /**
     * Downloads spreadsheet with given file id as an Excel file.
     * Uses Advanced Drive Service, which must be enabled.
     * Throws if error encountered.
     *
     * From http://stackoverflow.com/a/27281729/1677912
     *
     * @param {String}   fileId       File ID of Sheets file on Drive.
     */
    function downloadXLS(fileId) {
      var file = Drive.Files.get(fileId);
      var url = file.exportLinks[MimeType.MICROSOFT_EXCEL];
    
     var options = {
       headers: {
         Authorization:"Bearer "+ScriptApp.getOAuthToken()
       },
        muteHttpExceptions : true        /// Get failure results
      }
    
      var response = UrlFetchApp.fetch(url, options);
      var status = response.getResponseCode();
      var result = response.getContentText();
      if (status != 200) {
        // Get additional error message info, depending on format
        if (result.toUpperCase().indexOf("<HTML") !== -1) {
          var message = strip_tags(result);
        }
        else if (result.indexOf('errors') != -1) {
          message = JSON.parse(result).error.message;
        }
        throw new Error('Error (' + status + ") " + message );
      }
    
      var ss = SpreadsheetApp.openById('Spreadsheet ID');
      var sh = ss.getSheets()[0];// access first sheet (0 indexed)
      var row = sh.getLastRow();
      var data = sh.getRange(row, 2).getValue();
      var row2 = sh.getLastRow();
      var data2 = sh.getRange(row, 15).getValue();
      var doc = response.getBlob();
      DriveApp.createFile(doc).setName(data + "-" + data2 + '.xlsx').setDescription(data + "-" + data2);
    }
    
    
    // A JavaScript equivalent of PHP’s strip_tags
    // from http://phpjs.org/functions/strip_tags/
    function strip_tags(input, allowed) {
      allowed = (((allowed || '') + '')
        .toLowerCase()
        .match(/<[a-z][a-z0-9]*>/g) || [])
        .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
      var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
        commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
      return input.replace(commentsAndPhpTags, '')
        .replace(tags, function($0, $1) {
          return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
        });
    }
    }