代码之家  ›  专栏  ›  技术社区  ›  DanCue

谷歌应用程序脚本gmail csv导入到工作表错误

  •  0
  • DanCue  · 技术社区  · 7 年前

    我已经从各种谷歌搜索中拼凑出了这段代码,如果电子邮件有一个特定的标签,这些代码将提取电子邮件的csv附件。

    function importCSVFromGmail() { 
      //gets first(latest) message with set label
      var threads = GmailApp.getUserLabelByName('Dashboard Updates').getThreads(0,1);     
      var message = threads[0].getMessages()[0];
      var attachment = message.getAttachments()[0];
    
      // Is the attachment a CSV file
      if (attachment.getContentType() === "text/csv") {                            
        var ss = SpreadsheetApp.getActive();
        var sh = ss.getSheetByName("Monthly_Detail_Instantis");
        //parses content of csv to array
        var dataString = attachment.getDataAsString();
        var escapedString = dataString.replace(/(?=["'])(?:"[^"\\]*(?:\\[\s\S][^"\\]*)*"|'[^'\\]\r\n(?:\\[\s\S][^'\\]\r\n)*')/g, '\\r\\n');
        var csvData = Utilities.parseCsv(escapedString);
    
        // Remember to clear the content of the sheet before importing new data
        sh.clearContents().clearFormats();                                         
        //pastes array to sheet
        sh.getRange(1, 1, csvData.length, csvData[0].length).setValues(csvData);   
      }
    
      //marks the Gmail message as read and unstars it (Filter sets a star)
      message.markRead();                                                          
      message.unstar();                                                            
    
    }
    

    脚本运行良好,但是我遇到了带有逗号或引号值的单元格的问题。例如,如果单元格具有以下内容:

    1,000,000
    

    Google "Apps" Script
    

    它将分别返回到下面。

    \r\n
    
    \r\n\r\n\r\n
    

    我确定这与所用的regex有关,但是我不确定如何调整上面的内容。对此,任何帮助都将不胜感激。

    1 回复  |  直到 6 年前
        1
  •  0
  •   DanCue    7 年前

    我能够使用原始代码(在问题中使用)并用这个链接中的代码替换escaping和utilities.parsecsv。这将正确导入csv,即使单元格包含引号和逗号: https://productforums.google.com/forum/#!topic/docs/nhXjrl8JIek

    这是我的最终代码:

    function importCSVFromGmail() { 
      //gets first(latest) message with set label
      var threads = GmailApp.getUserLabelByName('Dashboard Updates').getThreads(0,1);     
      var message = threads[0].getMessages()[0];
      var attachment = message.getAttachments()[0];
    
      // Is the attachment a CSV file
      if (attachment.getContentType() === "text/csv") {                            
        var ss = SpreadsheetApp.getActive();
        var sh = ss.getSheetByName("Monthly_Detail_Instantis");
        //parses content of csv to array
        var dataString = attachment.getDataAsString();
        var csvData = CSVToArray(dataString);
    
        // Remember to clear the content of the sheet before importing new data
        sh.clearContents().clearFormats();                                         
        //pastes array to sheet
        var lastRowValue = sh.getLastRow();
        for (var i = 0; i < csvData.length; i++) {
           sh.getRange(i+lastRowValue+1, 1, 1, csvData[i].length).setValues(new Array(csvData[i]));
        } 
      }
    
      //marks the Gmail message as read and unstars it (Filter sets a star)
      message.markRead();                                                          
      message.unstar();                                                            
    
    }
    
    //The code formats the code so it can be entered into the Google Script
    
    function CSVToArray( strData, strDelimiter ){ 
      // Check to see if the delimiter is defined. If not,
      // then default to comma.
      strDelimiter = (strDelimiter || ",");
    
      // Create a regular expression to parse the CSV values.
      var objPattern = new RegExp(
        (
          // Delimiters.
          "(\\" + strDelimiter + "|\\r?\\n|\\r|^)" +
    
    
          // Quoted fields.
          "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +
    
    
          // Standard fields.
          "([^\"\\" + strDelimiter + "\\r\\n]*))"
        ),
        "gi"
      );
    
    
      // Create an array to hold our data. Give the array
      // a default empty first row.
      var arrData = [[]];
    
      // Create an array to hold our individual pattern
      // matching groups.
      var arrMatches = null;
    
      // Keep looping over the regular expression matches
      // until we can no longer find a match.
      while (arrMatches = objPattern.exec( strData )){
    
        // Get the delimiter that was found.
        var strMatchedDelimiter = arrMatches[ 1 ];
    
        // Check to see if the given delimiter has a length
        // (is not the start of string) and if it matches
        // field delimiter. If id does not, then we know
        // that this delimiter is a row delimiter.
        if (
          strMatchedDelimiter.length &&
          (strMatchedDelimiter != strDelimiter)
        ){
    
          // Since we have reached a new row of data,
          // add an empty row to our data array.
          arrData.push( [] );
    
        }
    
        // Now that we have our delimiter out of the way,
        // let's check to see which kind of value we
        // captured (quoted or unquoted).
        if (arrMatches[ 2 ]){
    
          // We found a quoted value. When we capture
          // this value, unescape any double quotes.
          var strMatchedValue = arrMatches[ 2 ].replace(
            new RegExp( "\"\"", "g" ),
            "\""
          );
    
        } else {
    
          // We found a non-quoted value.
          var strMatchedValue = arrMatches[ 3 ];
    
        }
    
        // Now that we have our value string, let's add
        // it to the data array.
        arrData[ arrData.length - 1 ].push( strMatchedValue );
      }
    
      // Return the parsed data.
      return( arrData );
    }