【问题标题】:Create excel document from google spreadsheet row从谷歌电子表格行创建excel文档
【发布时间】:2016-09-02 18:04:15
【问题描述】:

我正在使用此处找到的代码: 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 列和第 15 列中的值。正在工作
  4. 新的 excel 文件应放在文件夹“Form Responses”中,id=0B-eAmBjlnU16YTJIVVFpMjJoTzQ。 现在工作

我能够修改代码以在添加新行时触发,使用最后一行的值,第 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 : '';
    });
} 

我没有太多运气找到有关如何仅将特定范围导出为 excel 文件的信息(第 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,它在手动运行时可以工作,但我无法确定一个触发器,该触发器在新行被复制后立即工作。

【问题讨论】:

  • 要提出一个有效的问题,请向我们展示您的尝试。到目前为止,您似乎还没有尝试过编码。查看 SpreadsheetApp 文档。
  • 感谢您的评论。我添加了更多细节
  • 我现在有 4 个步骤中的 3 个。第二步可能是最困难的......
  • 代码的哪一部分是第2步,什么不起作用?
  • 我找不到很多关于仅将特定范围转换为 Excel 文档的详细信息,因此我尝试了另一种方法。见上面的编辑

标签: google-apps-script google-sheets


【解决方案1】:

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

总结: 该脚本将执行以下操作

  1. 将新行从一个电子表格移动到第二个电子表格 标题
  2. 根据第二个电子表格创建一个 excel 文件
  3. 将 excel 文件移动到特定文件夹
  4. 删除在第二个电子表格中创建的预期下一个新行的行

首先手动运行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 : '';
    });
}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 2021-04-22
    • 2011-07-30
    • 1970-01-01
    • 2016-01-03
    相关资源
    最近更新 更多