2016-02-13 198 views
2

我正在研究一個涉及Google Drive中csv文件的項目,該項目每分鐘都會使用新數據進行更新。Google Apps腳本Utilities.parseCsv()和替換字符 -

我已經構建了一個電子表格儀表板以使csv中的數據更有意義。

我犯了一個錯誤,假設我可以使用Google Spreadsheet function = importdata(url)從Google Drive中的CSV獲取數據到我的Google Spreadsheet中,但是,除非我公開CSV這對於安全和隱私原因是不可行的。即使我公開製作CSV並使用導入數據,進入的數據也是完全不正確且不可用的 - 它看起來不像實際的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

如果我只是導入使用谷歌表「文件」,「導入」和「替換當前工作表」相同的CSV,數據來自於罰款。這不是一個好的解決方案,因爲實際上我只需要在CSV更新和Google表格更新中的儀表板之間延遲幾分鐘時間。如果我必須手動上傳CSV文件,它會破壞系統的用途。

任何幫助將不勝感激。謝謝!

+0

您如何獲取上傳到您的Google雲端硬盤的csv文件?您可以使用Google的[Drive Rest API](https://developers.google.com/drive/v2/reference/files/insert),併發出HTTPS POST請求以上傳csv文件。 Apps腳本有一種方法可以使用UrlFetchApp.fetch()進行HTTPS POST請求。你在尋找一種不同的方式來上傳文件,或者解析內容的方式嗎? –

+0

我正在尋找解析內容的方法。我並沒有100%清楚csv是如何得到更新的,儘管如此,也許https發佈請求會起作用。 –

回答

2

你有沒有檢查文件的字符集?您可以在致電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'; 
} 
+0

感謝您的支持!當我嘗試代碼時,我得到了相同的奇怪字符。我也試着用'utt-8'和ascii作爲charset無濟於事。再次感謝您的建議。任何其他想法? –

+0

您是否知道生成此csv的人使用的編碼?如果你不這樣做,請嘗試使用程序來檢測字符集(例如,linux中的'file')。或者你能分享一個示例文件嗎? –

+0

我已經聯繫瞭解使用的編碼。我無法共享該文件,因爲它具有私人信息。將在Excel中打開CSV或下載並將其導入Google表格(兩者都可以正常工作),以便我可以匿名化影響編碼的數據以實現此線程的目的? –

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你可以看到什麼是無法識別的字符應該是..空格在我的情況。

+0

聰明,謝謝你。 –

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(); 

這個腳本在我的情況下也工作正常,如果我導入數字並在公式中使用它們。