求助:如何将文件夹中多份CSV合并到单个Google Sheets工作表?
合并文件夹中多行CSV到单个工作表(Google Apps Script)
问题说明
目前能将文件夹中多个CSV合并为带多标签页的表格,但想直接合并到单个工作表,原代码在获取范围时存在问题,本人JavaScript经验较少,寻求解决方法。
原代码:
function mergeSheets() { /* Retrieve the desired folder */ var myFolder = DriveApp.getFoldersByName("CSVfolder").next(); /* Get all spreadsheets that resided on that folder */ var spreadSheets = myFolder.getFilesByType("text/csv"); if (spreadSheets.hasNext()) { /* Create the new spreadsheet that you store other sheets */ var newSpreadSheet = SpreadsheetApp.create("Merged Sheets"); /* Iterate over the spreadsheets over the folder */ while(spreadSheets.hasNext()) { var sheet = spreadSheets.next(); /* Load the csv data */ var csvData = Utilities.parseCsv(sheet.getBlob().getDataAsString(), ","); /* Copy the sheet to the new merged Spread Sheet */ var newSheet = newSpreadSheet.insertSheet("import_"+sheet.getName()); for (var i=0;i<csvData.length;i++) { newSheet.appendRow(csvData[i]); } } } } function combineArrays() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const arrayData = []; const sheets = ss.getSheets(); for (i = 0; i < 3; i++) { const sh = sheets[i]; const sourceValues = sh.getDataRange().getValues(); arrayData.push(...sourceValues); Logger.log(arrayData); } ss.getSheetByName("Target Sheet").getRange(19, 19, arrayData.length, arrayData[0].length).setValues(arrayData); }
解决方案
直接在读取CSV阶段就把所有数据合并到一个数组,最后一次性写入单个工作表,跳过中间多标签页的步骤,既高效又避免范围错误。
修改后的完整代码:
function mergeCsvToSingleSheet() { // 目标文件夹名称 const folderName = "CSVfolder"; // 合并后的工作表名称 const mergedSheetName = "Merged Single Sheet"; // 获取目标文件夹 const folder = DriveApp.getFoldersByName(folderName).next(); // 获取文件夹内所有CSV文件 const csvFiles = folder.getFilesByType("text/csv"); // 存储所有合并后的数据 const mergedData = []; let isFirstFile = true; // 遍历每个CSV文件 while (csvFiles.hasNext()) { const file = csvFiles.next(); // 解析CSV内容为二维数组 const csvData = Utilities.parseCsv(file.getBlob().getDataAsString(), ","); if (isFirstFile) { // 第一个文件保留完整数据(包含表头) mergedData.push(...csvData); isFirstFile = false; } else { // 后续文件跳过表头,只添加数据行 mergedData.push(...csvData.slice(1)); } } // 创建新的表格 const newSpreadsheet = SpreadsheetApp.create("Merged CSV"); // 获取默认工作表并改名 const targetSheet = newSpreadsheet.getSheets()[0]; targetSheet.setName(mergedSheetName); // 写入合并后的数据 if (mergedData.length > 0) { targetSheet.getRange(1, 1, mergedData.length, mergedData[0].length).setValues(mergedData); } }
关键说明
- 直接合并数据:跳过中间导入多标签页的步骤,读取CSV后直接将数据追加到合并数组,减少冗余操作。
- 表头处理:通过
isFirstFile标记,只保留第一个CSV的表头,避免重复表头(如果你的CSV无表头,可删除该判断,直接mergedData.push(...csvData))。 - 范围写入修复:从A1单元格(
getRange(1,1,...))开始写入数据,避免原代码固定起始位置的错误;同时判断数据数组非空再写入,防止空数组导致的报错。 - 高效写入:用
setValues一次性写入所有数据,比循环appendRow效率提升明显,适合处理大量数据。
如果需要合并到已有的表格而非新建,可替换创建表格的代码块:
// 替换为目标表格的ID const existingSpreadsheetId = "你的表格ID"; const newSpreadsheet = SpreadsheetApp.openById(existingSpreadsheetId); // 获取目标工作表,不存在则新建 let targetSheet = newSpreadsheet.getSheetByName(mergedSheetName); if (!targetSheet) { targetSheet = newSpreadsheet.insertSheet(mergedSheetName); }
内容的提问来源于stack exchange,提问作者iceman
相关产品推荐
相关产品推荐

