使用node-csv来读写CSV文件
前言
我们经常遇到一个很常见的问题,就是从一个csv文件中读取数据。我们可以使用fs模块来得到文件的内容。在这之后,使用特定的库来做解析和进一步分析csv则会简单和方便得多。
现在有很多模块都提供了这个功能,比如neat-csv或者csv-parser。而本文要介绍的是node-csv这一个模块,让我们来看看它是如何使用的。
安装node-csv
这个模块是由csv-generate, csv-parse,csv-transform以及csv-stringify这几个包组成的。你可以按需安装,也可以把他们都一次性安装了。
首先我们来用默认设置来创建一个Node的项目:
npm init -y
下面我们来安装整个node-csv:
npm install node-csv
下面是csv文件的内容,你可以拷贝到一个csv文件中,我们用这个文件来做测试:
Account Name,Account Code,Type,Description Cash,101,Assets,Checking account balance Wages Payable,220,Liabilities,Amount owed to employes for hours not yet paid Rent expense,560,Expenses,Cost of occupied rented facilities during accounting period
使用csv-parse来读取CSV文件
我们可以使用node-csv中的csv-parse来读取csv文件。Csv-parse包提供了很多种方法来解析csv文件–你可以使用callbask,也可以使用stream+callback或者sync的API,当然也支持async的api。本文就使用stream+callback api以及同步的sync api。
Stream+Callback API
我们先来创建一个文件index.js,并且创建parser:
var fs = require('fs'); var parse = require('csv-parse'); var parser = parse({columns: true}, function (err, records) { console.log(records); }); fs.createReadStream(__dirname+'/chart-of-accounts.csv').pipe(parser);
这里,我们使用了fs和csv-parse模块,然后创建parser,这里第二个参数就是callback函数,我们可以在这个callback中访问records,或者就像例子中一样先把record打印出来。
这里我们使用的参数不是强制的,你可以使用下面这些参数:
- Delimiter: 默认是逗号,假如你的文件中使用的是别的分隔符,比如分号;,或者管道|你可以设置相关的选项。
- cast:这个选项的默认值是false,这个是用来表示是否把字符串转换成本机的数据类型。比如,一个列的日期域可以转换成Date。
- columns:这个选项是用来表示你是否使用object格式来产生record。默认值是false,也就是records是通过parser用arrays来产生的。假如设为true,parser就是从第一行的column来推测。
最后就是用fs打开文件,然后把它传入到parser中。下面我们来运行试试看:
node index.js
结果如下所示:
[ { 'Account Name': 'Cash', 'Account Code': '101', Type: 'Assets', Description: 'Checking account balance' }, { 'Account Name': 'Wages Payable', 'Account Code': '220', Type: 'Liabilities', Description: 'Amount owed to employes for hours not yet paid' }, { 'Account Name': 'Rent expense', 'Account Code': '560', Type: 'Expenses', Description: 'Cost of occupied rented facilities during accounting period' } ]
有了这个结果,你就可以对这些内容来进行各种处理了。
使用同步API
下面我们来使用同步API来实现:
var fs = require('fs').promises; var parse = require('csv-parse/lib/sync'); (async function () { const fileContent = await fs.readFile(__dirname+'/chart-of-accounts.csv'); const records = parse(fileContent, {columns: true}); console.log(records) })();
这里,我们和之前类似,也还是使用fs模块和csv-parse.这里我们创建了一个async的函数,在它里面我们使用readFile函数来读取内容个,然后使用await等待。
然后使用parser,第一个参数是文件的内容,第二个是一个object参数(这里我们把column设为true)。然后把它赋值给record,然后我们可以使用这个record。
[ { 'Account Name': 'Cash', 'Account Code': '101', Type: 'Assets', Description: 'Checking account balance' }, { 'Account Name': 'Wages Payable', 'Account Code': '220', Type: 'Liabilities', Description: 'Amount owed to employes for hours not yet paid' }, { 'Account Name': 'Rent expense', 'Account Code': '560', Type: 'Expenses', Description: 'Cost of occupied rented facilities during accounting period' } ]
使用csv Stringify来写csv文件
下面我们来看看如何把数据写到csv格式的文件中。这里,我们使用csv-stringify包。我们假设你已经得到一些JSON格式的数据,然后想把它写入到csv文件中。
var someData = [ { "Country": "Nigeria", "Population": "200m", "Continent": "Africa", "Official Language(s)": "English" }, { "Country": "India", "Population": "1b", "Continent": "Asia", "Official Language(s)": "Hindi, English" }, { "Country": "United States of America", "Population": "328m", "Continent": "North America", "Official Language": "English" }, { "Country": "United Kingdom", "Population": "66m", "Continent": "Europe", "Official Language": "English" }, { "Country": "Brazil", "Population": "209m", "Continent": "South America", "Official Language": "Portugese" } ]
Csv-stringify包也有一些API的选项,Callback API有很多简单的方式来把数据变成string。让我们来看看如何把上面的JSON数据变成string,然后写到文件中:
var fs = require('fs'); var stringify = require('csv-stringify'); stringify(someData, { header: true }, function (err, output) { fs.writeFile(__dirname+'/someData.csv', output); })
这里我们使用fs和csv-stringify模块,然后使用stringify函数,把数据变成string。我们也传入了一个包含header选项的object。最后,有一个callback函数用来把内容写到文件里。
别的类似cast,columns以及你delimiter也可以加入到选项中。我们例子中使用的是header选项为true来告诉stringifier在第一个record中加入列的名字。
这个代码产生的文件内容如下:
总结
node-csv是一个很小的模块来进行读写,转换csv数据的。我们使用了scv-parse模块来读取csv文件然后使用csv-stringify模块来转换成字符并写到文件中。
Recent Comments