csv-parse 常用 API 速查
csv-parse 是 Node.js 最流行的 CSV 解析库,是 csv 全家桶的一员。
官方文档:https://csv.js.org/parse/
1. 安装
npm install csv-parse
2. 三种调用方式
2.1 同步方式(小文件,简单场景)
const { parse } = require('csv-parse/sync')
// 传入字符串,返回二维数组
const records = parse('name,age\nTom,18\nJerry,2')
// => [ ['name','age'], ['Tom','18'], ['Jerry','2'] ]
2.2 回调方式
const { parse } = require('csv-parse')
parse('name,age\nTom,18', { columns: true }, (err, records) => {
if (err) throw err
console.log(records)
})
2.3 流式方式(大文件,边读边解析,不占内存)
const fs = require('fs')
const { parse } = require('csv-parse')
fs.createReadStream('big.csv')
.pipe(parse({ columns: true }))
.on('data', (row) => {
console.log(row) // 每读到一行触发一次
})
.on('end', () => {
console.log('解析完成')
})
.on('error', (err) => {
console.error(err)
})
3. 常用 options(选项)
| 选项 |
默认值 |
说明 |
delimiter |
',' |
分隔符。传数组如 [';', '\t'] 可自动检测 |
columns |
false |
true = 首行作为表头,返回对象数组;也可传数组自定义表头 |
relax_column_count |
false |
允许各行字段数不一致(默认不一致会抛错) |
relax_quotes |
false |
宽容处理非法引号(解决 Invalid Opening Quote 报错的救急选项) |
quote |
'"' |
引号字符。设为 false 彻底禁用引号语法 |
escape |
'"' |
引号内的转义字符(默认双引号转义) |
bom |
false |
自动去掉 UTF-8 BOM 头 |
trim / ltrim / rtrim |
false |
去除字段两端 / 左端 / 右端空格 |
from_line / to_line |
1 / 不限 |
只解析指定行区间(行号从 1 开始) |
from / to |
1 / 不限 |
只解析第 N 条记录开始/结束(跳过解析出的记录数) |
skip_empty_lines |
false |
跳过空行 |
comment |
无 |
注释行前缀,如 '#',该行被忽略 |
cast |
false |
true = 自动类型转换(数字、布尔);也可传函数 (value, context) => ... |
cast_date |
false |
自动识别日期并转为 Date 对象 |
on_record |
无 |
每条记录的回调函数,返回 null 可跳过该行 |
encoding |
'utf8' |
输入编码(流式方式下常用) |
record_delimiter |
自动 |
行分隔符,如 '\n'、'\r\n'、';' |
4. 常见组合示例
4.1 表头模式:返回对象数组
const { parse } = require('csv-parse/sync')
const records = parse('name,age\nTom,18\nJerry,2', { columns: true })
// => [ { name: 'Tom', age: '18' }, { name: 'Jerry', age: '2' } ]
4.2 只取指定行区间
parse(text, { from_line: 2, to_line: 5 }) // 只要第 2~5 行
4.3 制表符分隔 + 去空格(TSV)
parse(text, { delimiter: '\t', trim: true })
4.4 跳过注释行和空行
parse(text, {
comment: '#',
skip_empty_lines: true,
})
4.5 逐行过滤(on_record)
parse(text, {
relax_column_count: true,
on_record: (record) => {
// 返回 null 跳过该行
if (!String(record[0]).trim()) return null
return record
},
})
4.6 自动类型转换
parse('name,age,active\nTom,18,true', { columns: true, cast: true })
// => [ { name: 'Tom', age: 18, active: true } ]
4.7 多分隔符自动检测
parse(text, { delimiter: [',', ';', '\t'] }) // 用检测到的第一个
5. 输出格式对照
| 配置 |
输入 a,b\n1,2 的输出 |
| 默认 |
[ ['a','b'], ['1','2'] ](二维数组) |
{ columns: true } |
[ { a: '1', b: '2' } ](对象数组) |
{ columns: ['x','y'] } |
[ { x: '1', y: '2' } ](自定义表头) |
{ cast: true } |
[ ['a','b'], [1,2] ](自动转型) |
6. 常见报错与处理
| 报错 |
原因 |
解决 |
Invalid Opening Quote |
非法引号(常见于文件编码错误导致乱码、或字段中间出现引号) |
先确认文件编码;确认无误后加 relax_quotes: true |
Invalid Closing Quote |
引号未闭合 |
同上 |
Column count inconsistency on line N |
各行列数不一致 |
加 relax_column_count: true |
乱码 / � 字符 |
文件不是 UTF-8(如 UTF-16/GBK) |
用正确编码读取;UTF-16 开头字节为 FF FE,可先 Format-Hex 检查 |
7. csv 全家桶
| 包 |
作用 |
csv-parse |
解析 CSV(文本 → 数据) |
csv-stringify |
生成 CSV(数据 → 文本),解析的逆操作 |
stream-transform |
流式转换(边读边改数据) |
csv |
上面三者的聚合包,一条链路搞定 parse → transform → stringify |
// csv 聚合包示例:读入、转换、输出一条链
const { parse } = require('csv-parse')
const { stringify } = require('csv-stringify')
const transform = require('stream-transform')
fs.createReadStream('in.csv')
.pipe(parse({ columns: true }))
.pipe(transform((row) => ({ ...row, extra: 'x' })))
.pipe(stringify({ header: true }))
.pipe(fs.createWriteStream('out.csv'))