0

我正在尝试自动下载 Google 表格 -> 管道分隔的文本文件。基本上,我想创建一个时间驱动的脚本以在 Google 电子表格上运行,以将其保存为带有|分隔符的 .txt。

电子表格本身是一个单一的工作表,它使用 IMPORTRANGE 从我的主文件中提取数据以供最终用户访问。

现在我手动将它下载为.csv,在记事本中打开它,用|'s'替换所有逗号,然后另存为.txt,然后将该文件上传到需要去的地方(上传无关紧要,必须是手动的) . 我想为自己自动化,但也让另一个用户在我不可用时通过脚本获取最终的 .txt 文件。最重要的是,我希望它能够在没有用户输入或活动工作站的情况下运行(它应该在周日早上运行),因此它必须在时间触发的 Google Apps 脚本中。

我的 JavaScript 经验很少,所以我能想到的唯一解决方案是两个嵌套的 for 循环(sheetIDsheetName保留):

  var ss= SpreadsheetApp.openById(sheetID)
  var pipeDelimitedString = ""
  var sheet = ss.getSheetByName(sheetName)
  var lastRow = sheet.getLastRow()
  var lastColumn = sheet.getLastColumn()
  var fileName = "PIPE DELIMITED TEST FILE"
  for (var i=1;i<=lastRow;i++){
        for(var j=1;j<=lastColumn;j++){
            if (j==lastColumn){
                 pipeDelimitedString = pipeDelimitedString + "|" + sheet.getRange(i,j).getValue()+"/n"
            } else {
                 pipeDelimitedString = pipeDelimitedString + "|" + sheet.getRange(i,j).getValue()
            }
        }
}
newFile = DriveApp.createFile(fileName,pipeDelimitedString);

然后是一个小脚本,将 newFile 通过电子邮件发送给其他用户(还没有写那部分,但我在 google 上看到了很多解决方案,所以不用担心电子邮件部分)

这必须在 66 列和最多 200 行(>10k 总单元格)的工作表上运行。我在只有约 50 行的数据集上对其进行了测试,我不得不停止它。即使它确实有效,它也会占用我太多用于触发脚本的 Google Apps 脚本配额。

我确定我已经走错了方向。请帮忙?即使只是从哪里开始也将不胜感激。

我无法共享实际文件,只能共享一个虚拟副本,但我很确定解决方案不应该是特定于内容的?除了原始文件数据中没有逗号或管道这一事实之外,如果有帮助,只有文本和数字的混合?

4

2 回答 2

1

如果你不喜欢嵌套循环,你可以使用更多花哨的工具:

var sheetID = "";
var sheetName = "";

function myFunction() {

  var ss         = SpreadsheetApp.openById(sheetID);
  var sheet      = ss.getSheetByName(sheetName);
  var lastRow    = sheet.getLastRow();
  var lastColumn = sheet.getLastColumn();
  var range      = sheet.getRange(1,1,lastRow,lastColumn).getValues(); <-- get all values

  var pipeDelimitedString = range.map(r => r.join("|")).join("\n"); <-- instead of loop

}

甚至更短,没有lastRowlastColumn变量:

function myFunction() {

  var ss    = SpreadsheetApp.openById(sheetID);
  var sheet = ss.getSheetByName(sheetName);
  var range = sheet.getDataRange().getValues();
  var pipeDelimitedString = range.map(r => r.join("|")).join("\n");

}

要点是getRange().getValues()一次用于所有单元格。

更新

要删除表格外的空行和单元格,您可以将replace()方法应用于字符串变量:

pipeDelimitedString = pipeDelimitedString.replace(/\|+\s*\|+/g, "");

这是一个最简单的解决方案。但请注意,replace()如果您的表格内部有 emply 单元格,该方法会得到错误的结果。1| |A会变成1A. 需要更复杂的算法来保持内部空单元格的完整性。实施很大程度上取决于您的数据。

在:

在此处输入图像描述

出去:

在此处输入图像描述

于 2021-05-04T23:35:22.510 回答
1
function myFunction() {
  const ss = SpreadsheetApp.openById(gobj.globals.ssid);//Change your id
  let s = ""
  const sh = ss.getSheetByName('Sheet1');//change your sheet name
  let vs = sh.getRange(1,1,sh.getLastRow(),sh.getLastColumn()).getValues();//getting all of the data on the sheet
  vs.forEach(r=>{r.forEach(c=>{s+="|" + c;});s+='\n';});//two loops
  newFile = DriveApp.createFile("PIPE DELIMITED TEST FILE", s);//you could add a folder
}

ascii 文件如下所示:

|COL1|COL2|COL3|COL4|COL5|COL6|COL7|COL8|COL9|COL10
|6|2|4|9|5|0|5|9|4|0
|5|1|5|7|1|2|5|7|0|0
|6|8|7|2|4|7|6|3|0|9
|7|5|7|6|3|2|7|7|0|0
|3|1|9|4|2|2|5|6|1|8
|7|8|8|3|2|7|1|6|3|0
|4|5|2|4|6|8|5|4|6|2
|9|3|6|7|5|7|9|9|0|6
|3|2|3|0|1|4|3|6|8|0
|9|0|0|2|8|0|0|2|4|7

对于此表:

COL1 COL2 COL3 COL4 COL5 COL6 COL7 COL8 COL9 COL10
6 2 4 9 5 0 5 9 4 0
5 1 5 7 1 2 5 7 0 0
6 8 7 2 4 7 6 3 0 9
7 5 7 6 3 2 7 7 0 0
3 1 9 4 2 2 5 6 1 8
7 8 8 3 2 7 1 6 3 0
4 5 2 4 6 8 5 4 6 2
9 3 6 7 5 7 9 9 0 6
3 2 3 0 1 4 3 6 8 0
9 0 0 2 8 0 0 2 4 7
于 2021-05-04T23:42:50.990 回答