如何在Angular 6项目中用TypeScript无第三方库正确读取含引号内换行符的CSV文件
解决带引号字段内换行的CSV解析问题(TypeScript/Angular 6)
我完全懂你的困扰——直接用split(/\r\n/)拆分CSV时,带双引号字段里的换行符会被误当成记录分隔符,把一条完整的记录拆成两半。既然没法用第三方库,咱们自己实现一个轻量的符合CSV规范的解析器就行,核心是跟踪是否处于引号包裹的字段内,只在引号外的换行符处拆分记录。
实现思路
CSV的核心规则我们只要抓住两点:
- 被双引号
"包裹的字段内,逗号、\r\n/\n都属于字段内容,不算分隔符 - 如果字段内需要出现双引号,会用连续两个双引号
""来转义(比如"He said ""Hello"""实际表示字段内容是He said "Hello")
基于这个规则,我们可以逐个字符遍历CSV内容,维护几个状态:
- 当前正在构建的字段内容
- 当前正在构建的记录
- 是否处于引号包裹的状态中
TypeScript 实现代码
下面是可以直接用的解析函数,适配你的Angular 6项目:
function parseCsv(csvContent: string): string[][] { const result: string[][] = []; let currentRecord: string[] = []; let currentField = ''; let inQuotes = false; // 遍历每个字符,处理所有换行符情况(\r\n、\n) const chars = csvContent.split(''); for (let i = 0; i < chars.length; i++) { const char = chars[i]; // 处理双引号:切换引号状态,或者处理转义的双引号 if (char === '"') { // 如果下一个字符也是双引号,说明是转义的,添加一个双引号到字段 if (i + 1 < chars.length && chars[i + 1] === '"') { currentField += '"'; i++; // 跳过下一个引号 } else { inQuotes = !inQuotes; } continue; } // 处理换行符:只有不在引号内时,才结束当前记录 if ((char === '\n' || char === '\r') && !inQuotes) { // 跳过\r后面的\n(处理\r\n组合) if (char === '\r' && i + 1 < chars.length && chars[i + 1] === '\n') { i++; } // 把当前字段加入记录,记录加入结果 currentRecord.push(currentField.trim()); // 可选:trim掉字段前后的空格,根据需求调整 result.push(currentRecord); currentRecord = []; currentField = ''; continue; } // 处理逗号:只有不在引号内时,才结束当前字段 if (char === ',' && !inQuotes) { currentRecord.push(currentField.trim()); // 可选trim currentField = ''; continue; } // 其他字符直接加入当前字段 currentField += char; } // 处理最后一条没有换行符的记录 if (currentField.length > 0) { currentRecord.push(currentField.trim()); result.push(currentRecord); } return result; }
在你的Angular代码中使用
把这个函数集成到你的reader.onload回调里就行:
reader.onload = () => { const csvData = reader.result as string; const parsedRecords = parseCsv(csvData); // 现在parsedRecords就是正确解析后的二维数组了 console.log(parsedRecords); // 输出示例: // [ // [ // "INC2289067", // "This is Description\r\nSomething\nAnotherthing", // "2020-14-07 01:14:00", // "2020-16-07 09:35:00", // "CORP - CAD L2", // "GIS AP PC Support", // "4 - Low", // "Solved (Permanently)", // "FALSE", // "2" // ] // ] };
关键细节说明
- 处理了
\r\n和\n两种换行符,同时避免重复处理\r\n中的两个字符 - 正确识别转义的双引号
"",将其转换为单个"存入字段 - 可选的
trim():如果你的CSV字段前后可能有空格,可以保留;如果字段内容需要保留原始空格,去掉trim()即可 - 兼容最后一条记录没有换行符的情况
内容的提问来源于stack exchange,提问作者mebunnu
相关产品推荐
相关产品推荐

