Parse and Process CSV Files with Google Apps Script

CSV files are one of the most common data exchange formats. Apps Script can read them from Drive, parse them into arrays, and process or import the data into Sheets — all without any external libraries.

Read a CSV file from Google Drive

function readCsvFromDrive() { const fileId = 'YOUR_CSV_FILE_ID'; // Get this from the file's Drive URL const file = DriveApp.getFileById(fileId); const content = file.getBlob().getDataAsString(); Logger.log(content); // Raw CSV text }

Parse CSV text into a 2D array

Apps Script doesn't have a built-in CSV parser, but Utilities.parseCsv() handles it cleanly:

function parseCsv() { const fileId = 'YOUR_CSV_FILE_ID'; const file = DriveApp.getFileById(fileId); const content = file.getBlob().getDataAsString(); const rows = Utilities.parseCsv(content); // rows is a 2D array: rows[0] is the header, rows[1..n] are data rows rows.forEach((row, i) => { Logger.log(`Row ${i}: ${row.join(' | ')}`); }); }

Utilities.parseCsv() handles quoted fields and commas within values correctly.

Import CSV data into a Google Sheet

function importCsvToSheet() { const fileId = 'YOUR_CSV_FILE_ID'; const file = DriveApp.getFileById(fileId); const content = file.getBlob().getDataAsString(); const rows = Utilities.parseCsv(content); const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); sheet.clearContents(); // Write all rows at once (much faster than appendRow in a loop) sheet.getRange(1, 1, rows.length, rows[0].length).setValues(rows); Logger.log(`Imported ${rows.length} rows.`); }

Filter rows during import

function importFilteredCsv() { const fileId = 'YOUR_CSV_FILE_ID'; const content = DriveApp.getFileById(fileId).getBlob().getDataAsString(); const rows = Utilities.parseCsv(content); const headers = rows[0]; const statusIndex = headers.indexOf('Status'); // Find the "Status" column // Only import rows where Status === "Active" const filtered = rows.filter((row, i) => i === 0 || row[statusIndex] === 'Active'); const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); sheet.clearContents(); sheet.getRange(1, 1, filtered.length, filtered[0].length).setValues(filtered); Logger.log(`Imported ${filtered.length - 1} active rows.`); }

Process a CSV without writing to a Sheet

function processCsvData() { const fileId = 'YOUR_CSV_FILE_ID'; const content = DriveApp.getFileById(fileId).getBlob().getDataAsString(); const rows = Utilities.parseCsv(content); const headers = rows[0]; const dataRows = rows.slice(1); // Convert to array of objects const records = dataRows.map(row => { const obj = {}; headers.forEach((header, i) => { obj[header.trim()] = row[i]; }); return obj; }); // Example: sum a numeric column const total = records.reduce((sum, r) => sum + parseFloat(r['Amount'] || 0), 0); Logger.log('Total Amount: ' + total); }

Watch a Drive folder and auto-import new CSVs

function processNewCsvFiles() { const folderId = 'YOUR_FOLDER_ID'; const processedKey = 'PROCESSED_FILES'; const folder = DriveApp.getFolderById(folderId); const processed = JSON.parse( PropertiesService.getScriptProperties().getProperty(processedKey) || '[]' ); const files = folder.getFilesByType('text/csv'); while (files.hasNext()) { const file = files.next(); if (processed.includes(file.getId())) continue; const content = file.getBlob().getDataAsString(); const rows = Utilities.parseCsv(content); // Process rows here... Logger.log(`Processing: ${file.getName()} (${rows.length} rows)`); processed.push(file.getId()); } PropertiesService.getScriptProperties().setProperty(processedKey, JSON.stringify(processed)); }

Tips

  • Use file.getBlob().getDataAsString('UTF-8') if your CSV has non-ASCII characters.
  • Utilities.parseCsv() handles standard RFC 4180 CSV — quoted fields, embedded commas, and newlines within quotes all work.
  • Writing all rows at once with setValues() is dramatically faster than looping with appendRow().