如何在Javascript中使用while循环逐行读取.csv文件并存入数组
嘿,既然你已经在C#里搞定了逐行读CSV存数组的功能,那在JavaScript里实现其实也挺 straightforward 的,不过得区分浏览器端和Node.js端两种场景——毕竟JS在不同环境下处理文件的方式差得挺多。下面分别给你用while循环实现的方案:
Node.js 环境下的实现
在Node.js里,我们可以借助内置的fs和readline模块来实现流式逐行读取,配合async迭代器和while循环就能轻松搞定:
const fs = require('fs'); const readline = require('readline'); async function readCsvToArray(filePath) { const csvArray = []; // 创建逐行读取的接口,兼容不同换行符 const rl = readline.createInterface({ input: fs.createReadStream(filePath), crlfDelay: Infinity }); // 获取async迭代器,用while循环逐行遍历 const lineIterator = rl[Symbol.asyncIterator](); let currentLine; while (!(currentLine = await lineIterator.next()).done) { const rawLine = currentLine.value; // 这里简单用split(',')拆分列,注意:复杂CSV(带引号包裹的逗号)需要用专业库 const rowData = rawLine.split(','); csvArray.push(rowData); } rl.close(); return csvArray; } // 调用示例 readCsvToArray('./your-file.csv') .then(result => console.log('读取完成:', result)) .catch(err => console.error('读取出错:', err));
如果你的CSV格式比较复杂(比如单元格里包含逗号、换行或者引号),手动split会出问题,这时候建议用papaparse这类专门的CSV解析库,它支持流式逐行处理,能完美处理各种边缘情况。
浏览器端的实现
浏览器里不能直接读取本地文件,必须通过用户上传的方式获取文件对象。这里分两种情况:
小文件:一次性读取后用while循环遍历
如果文件不大,可以先把整个文件读成文本,再分割成行,用while循环处理:
<input type="file" id="csvUploader" accept=".csv"> <script> async function handleCsvUpload(event) { const selectedFile = event.target.files[0]; if (!selectedFile) return; const csvArray = []; // 读取文件为文本内容 const fileText = await selectedFile.text(); // 分割成行,兼容Windows和Unix换行符 const allLines = fileText.split(/\r?\n/); // 用while循环逐行处理 let lineIndex = 0; while (lineIndex < allLines.length) { const line = allLines[lineIndex].trim(); // 跳过空行 if (line) { const row = line.split(','); csvArray.push(row); } lineIndex++; } console.log('CSV转换结果:', csvArray); } document.getElementById('csvUploader').addEventListener('change', handleCsvUpload); </script>
大文件:流式逐行读取
如果是超大CSV文件,一次性加载会占用过多内存,这时候可以用ReadableStream来流式处理,配合while循环逐块读取并解析:
<input type="file" id="largeCsvUploader" accept=".csv"> <script> async function streamReadLargeCsv(file) { const csvArray = []; const reader = file.stream().getReader(); const decoder = new TextDecoder('utf-8'); let incompleteLine = ''; // 存储上一块未完成的行 while (true) { const { done, value } = await reader.read(); if (done) { // 处理最后剩下的内容 if (incompleteLine.trim()) { csvArray.push(incompleteLine.split(',')); } break; } // 解码当前块的内容 const chunkText = decoder.decode(value, { stream: true }); // 合并上一块的剩余内容,再分割成行 const lines = (incompleteLine + chunkText).split(/\r?\n/); // 最后一行可能不完整,留到下一块处理 incompleteLine = lines.pop(); // 用while循环处理当前块的所有完整行 let lineIndex = 0; while (lineIndex < lines.length) { const line = lines[lineIndex].trim(); if (line) { csvArray.push(line.split(',')); } lineIndex++; } } return csvArray; } // 绑定上传事件 async function handleLargeCsvUpload(event) { const file = event.target.files[0]; if (!file) return; const result = await streamReadLargeCsv(file); console.log('大文件读取完成:', result); } document.getElementById('largeCsvUploader').addEventListener('change', handleLargeCsvUpload); </script>
同样,如果是复杂格式的CSV,推荐用papaparse浏览器版,它自带流式解析功能,不用自己处理这些细节~
内容的提问来源于stack exchange,提问作者ThePat02
相关产品推荐
相关产品推荐

