如何在JavaScript中将.csv文件转换为二维数组/矩阵
解决CSV读取并转换为二维数组的问题
问题根源
text变量是在reader.onload回调函数内部定义的局部变量,外部无法访问,这就是你遇到“text未定义”错误的核心原因。document.write会清空当前页面内容,不适合用来调试或展示读取结果。
解决方案
1. 调整逻辑,在回调内完成CSV转换
FileReader读取文件是异步操作,所有依赖读取结果的逻辑必须放在onload回调里。下面是修改后的完整代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <form id="myForm"> <input type="file" id="csvFile" accept=".csv" /> <br /> <input type="submit" value="Submit" /> <div id="result"></div> <!-- 用于展示转换结果 --> </form> <script> const myForm = document.getElementById("myForm"); const csvFile = document.getElementById("csvFile"); const resultDiv = document.getElementById("result"); // 将CSV字符串转为二维数组的基础函数 function csvToMatrix(csvText) { // 按换行分割行,过滤空行 const rows = csvText.split('\n').filter(row => row.trim() !== ''); // 每行按逗号分割为列,返回二维数组 return rows.map(row => row.split(',').map(cell => cell.trim())); } myForm.addEventListener("submit", function (e) { e.preventDefault(); const input = csvFile.files[0]; if (!input) { resultDiv.textContent = "请先选择一个CSV文件"; return; } const reader = new FileReader(); reader.onload = function (e) { const text = e.target.result; // 转换为二维数组 const csvMatrix = csvToMatrix(text); // 控制台打印结果,方便调试 console.log("转换后的二维数组:", csvMatrix); // 在页面展示格式化后的结果 resultDiv.innerHTML = `<pre>${JSON.stringify(csvMatrix, null, 2)}</pre>`; }; reader.readAsText(input); }); </script> </body> </html>
2. 处理复杂CSV场景(可选)
上面的基础函数假设CSV字段中没有逗号包裹在引号内的情况(比如"张三,男",25这类带逗号的字段),如果需要兼容这种复杂格式,可以使用更健壮的解析函数:
function csvToMatrixAdvanced(csvText) { const rows = []; const regex = /("([^"]|"")*"|[^",\n]*)(,|\n)/g; let matches; let currentRow = []; while ((matches = regex.exec(csvText)) !== null) { const [, cell,, separator] = matches; // 去掉字段首尾引号,替换内部双引号为单引号 const cleanedCell = cell.replace(/^"|"$/g, '').replace(/""/g, '"'); currentRow.push(cleanedCell.trim()); // 遇到换行符时,结束当前行并加入结果数组 if (separator === '\n') { rows.push(currentRow); currentRow = []; } } // 处理最后一行(如果文件末尾没有换行符) if (currentRow.length > 0) { rows.push(currentRow); } return rows; }
关键注意点
- 所有依赖CSV内容的操作必须放在
reader.onload回调内,因为文件读取是异步的,只有回调触发时才真正拿到文件内容。 - 避免使用
document.write,改用页面元素或控制台输出结果,防止页面被意外清空。 - 如果需要在回调外部使用转换后的数组,可以将其赋值给全局变量,或者用Promise封装读取逻辑(适合更复杂的业务场景)。
内容的提问来源于stack exchange,提问作者K_Grabska
相关产品推荐
相关产品推荐

