Google Apps脚本Utilities.parseCsv()和替换字符 - �

时间:2016-02-13 06:55:09

标签: csv google-apps-script google-sheets

我正在处理一个项目,该项目涉及Google云端硬盘中的csv文件,该文件每分钟都会更新一次新数据。

我已经构建了一个电子表格信息中心,以使csv中的数据更有意义。

我错误地假设我可以使用Google Spreadsheet function = importdata(url)将Google云端硬盘中的CSV数据导入我的Google电子表格,但是,除非我公开CSV,否则会产生错误,出于安全和隐私原因,这是不可行的。即使我公开使用CSV并使用importdata,但进入的数据完全格式错误且无法使用 - 它看起来与实际的CSV完全不同。

malformed data with importdats(url)

我尝试编写脚本以使用DriveApp自动导入csv数据以打开csv文件,Utilities.parseCsv将csv转换为数据数组,然后使用setValues将数据写入工作表

function importData() {
  var ss = SpreadsheetApp.getActive();
  var file = DriveApp.getFilesByName("Agent Performance.csv")
  var csv = file.next().getBlob().getDataAsString();
  var csvData = Utilities.parseCsv(csv);
  var sheet = ss.getSheetByName('CSV Import TEST');
  for (var i = 0; i < csvData.length; i++) {
    sheet.getRange(i+1, 1, 1, csvData[i].length).setValues(new Array(csvData[i]));
  }
}

问题是我得到了替换字符,例如:�所有写入工作表的数据。太奇怪了。工作表看起来很正常,但是如果单击一个单元格来查看它的值,则公式栏中包含单元格中的文本,但每个字符之间都是�。这使得Google表格中的任何计算都不可能。

Notice replacement characters in formula bar

如果我只是使用Google表格导入相同的CSV&#34;文件&#34;和&#34;导入&#34;和&#34;替换当前表&#34;,数据正常。这不是一个很好的解决方案,因为实际上我想要在CSV更新和Google表格更新中的仪表板之间延迟不超过几分钟。如果我必须手动上传CSV,则会破坏系统的目的。

非常感谢任何帮助。谢谢!

3 个答案:

答案 0 :(得分:3)

你检查文件字符集了吗?您可以在致电getDataAsString(charset)时指定它。试试这个:

function importData() {
  var ss = SpreadsheetApp.getActive();
  var file = DriveApp.getFilesByName("Agent Performance.csv")
  var csv = file.next().getBlob().getDataAsString('ISO-8859-1'); //note the charset
  var csvData = Utilities.parseCsv(csv);
  //unless you csv has variable amount of columns per line, you should do this
  if(csvData.length > 0) {
    ss.getSheetByName('CSV Import TEST')
      .getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);
  } else
    throw 'Blank file';
}

答案 1 :(得分:1)

这可能会有所帮助,但您可能需要调查是否会导致数据出现其他问题:

我在导入包含银行交易数据的.txt文件时遇到同样的问题,因为银行不提供CSV下载文件。我发现奇数字符是FFFD,似乎是由fileXYZ.getblob()方法插入的,作为无法识别的代码的unrecognized字符的替代,在我的情况下,它们被空格替换。

一旦你加载了文件,我的(非常基本的)解决方案如下..

function getBankTransactionFile(fileNameToGet) {
// fileNameToGet is .txt and stored in folder specified in Var list

 var  inputFileFolderID = '0B2XXX insert your folder ID',
     fldrID = DriveApp.getFolderById(inputFileFolderID),
     theFileRetrieved = fldrID.getFilesByName('yourFileName'),
     csvFile, cntFiles = 0;

// Even if it's only one file, must iterate a while loop in order to access the file. Google drive will allow multiple files of the same name.
  while (theFileRetrieved.hasNext()) {
    var fileXYZ = theFileRetrieved.next();
    cntFiles = cntFiles + 1;
    csvFile = Utilities.parseCsv(fileXYZ.getBlob()
              .getDataAsString().replace('\uFFFD'," ",'g'), "\n")
    // Utilities.parseCsv(csv, delimiter) returns 2D array but the fileXYZ 
    // text loaded has FFFD characters inserted so these are substituted for
    // 'space' using the .replace method and 'g' for global flag
  }
  return csvFile;
}

我是GAS的新手(从VBA转换),所以非常确定有更精确的方法,但它适用于我的数据..请注意\n是换行符作为我的数据的指定分隔符。我通过使用Logger显示原始数据字符串,然后提取计算字符的代码.charCodeAt(n)来查找n,从而找出了奇怪的字符。由于.txtimport,您可以看到无法识别的字符应该是什么..在我的情况下是空格。

答案 2 :(得分:0)

我对csv文件有同样的要求和相同的问题。我所做的可能是一种解决方法,但对我来说至少是好的。

“ ”实际上可能是任何类型的ASCII字符都无法识别,所以在我的情况下搜索“\ uFFFD”并没有解决问题。所以我所做的基本上是转换二进制数据中的有效载荷。在那里我设法注意到在所有字符之间传递了一个NULL(ASCII代码0)。这是我的情况 。所以我所做的是重建没有0的字节数组,然后再次在电子表格中复制它。

var response = UrlFetchApp.fetch(theUrl);
var payload = response.getContentText();
//Get byte Array 
var bytes= response.getContent();
var myArray = [];
//Build byte array without the faulty characters
for ( var i =1 ; i<bytes.length; i++){
  if (bytes[i] != 0){
   myArray.push(bytes[i]);
  }
}
//Reconvert to string.
var newArray = Utilities.newBlob(myArray).getDataAsString();

如果我导入数字并在公式中使用它们,我的情况下这个脚本也可以正常工作。