Вступление
Обычная задача разработки - чтение данных из файлов. Распространенным
форматом файлов является формат .csv
Хотя вы можете читать файлы CSV с помощью fs
который поставляется с
Node, и получать содержимое файла, в большинстве случаев синтаксический
анализ и дальнейшее преобразование намного проще с помощью модулей,
созданных именно для этой цели.
Несколько модулей предоставляют такие возможности, как пакеты neat-csv
или csv-parser
Однако в этой статье мы будем использовать
node-csv
- набор пакетов CSV для генерации,
анализа, преобразования и преобразования данных CSV в строку.
Установка node -csv
Модуль состоит из пакетов csv-generate
, csv-parse
, csv-transform
и csv-stringify
Вы можете установить весь пакет или каждый пакет по отдельности, если они вам не нужны. Давайте инициализируем проект Node с настройками по умолчанию:
$ npm init -y
Затем давайте установим весь пакет node-csv
$ npm install node-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 с помощью csv-parse
Для чтения файлов CSV мы будем использовать пакет
csv-parse
node-csv
.
Пакет csv-parse
предоставляет несколько подходов к синтаксическому
анализу файлов CSV - с использованием обратных вызовов, потока +
обратного вызова, а также Sync и Async API. Мы рассмотрим API потока +
обратного вызова и 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
который принимает литерал
объекта, содержащий параметры, которые мы хотим установить. Второй
аргумент - это функция обратного вызова, которая используется для
доступа к записям - или просто для их распечатки, в нашем случае.
Параметры, которые мы можем установить, не являются обязательными. В
большинстве случаев вы будете использовать любой из параметров
delimiter
, cast
или columns
:
-
Опция разделителя по умолчанию запятой
,
. Если в данных из файла, который вы пытаетесь проанализировать, используется другой разделитель, например точка с запятой;
, или труба|
, вы можете указать это с помощью этой опции. -
Параметр приведения по умолчанию имеет значение
false
и используется, чтобы указать, хотите ли вы привести строки к их собственным типам данных. Например, столбец, состоящий из полей даты, можно преобразовать вDate
. -
Параметр столбцов указывает, хотите ли вы создать запись в виде объектных литералов. По умолчанию для этого столбца установлено значение
false
а записи генерируются анализатором в виде массивов. Если установлено значениеtrue
, синтаксический анализатор будет выводить имя столбца из первой строки.
Наконец, мы открыли поток чтения с помощью fs
и начали передавать его
в синтаксический анализатор.
Запустим этот файл:
$ 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'
}
]
Вместо того, чтобы просто распечатывать содержимое, вы можете манипулировать этими данными, создавать объекты с информацией из этих полей или, например, сохранять их в базе данных.
Использование Sync API
Давайте воспроизведем эту функциональность с помощью Sync 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
и Sync API из модуля csv-parse
Затем мы создаем async
функцию, в которой мы получаем содержимое
файла, await
ответа от функции readFile()
.
Затем мы можем создать parser
который принимает содержимое файла в
качестве первого аргумента и литерала объекта в качестве второго. Этот
литерал объекта содержит параметры для создания парсера (мы установили
для columns
значение true
). Этому парсеру присваивается постоянная
переменная, и для краткости мы просто распечатываем его содержимое:
[
{
'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 с использованием CSV Stringify
Подобно чтению, мы иногда хотели бы записать данные в формат CSV. Для
этого мы будем использовать
csv-stringify
из пакета node-csv
.
Стренификация просто означает, что мы конвертируем некоторые данные (в
нашем примере JSON) в строку. Затем эта строка записывается в файл в
формате CSV.
Предположим, у вас есть содержимое 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, однако API
обратного вызова предлагает действительно простой способ
структурирования данных без необходимости обрабатывать события, как в
Stream API.
Давайте продолжим и приведем данные выше в строку, прежде чем записывать их в файл:
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()
, мы передаем данные, которые хотим преобразовать в
строку. Мы также предоставили литерал объекта, содержащий параметр
header
. Наконец, есть также функция обратного вызова, которая
используется для записи содержимого в файл.
Также доступны другие параметры, такие как cast
, columns
и
delimiter
. В нашем случае мы устанавливаем для параметра header
значение true
чтобы указать строковому преобразователю сгенерировать
имена столбцов в первой записи.
При запуске этого кода создается файл с правильным содержимым:
{.ezlazyload}
Заключение
Модуль node-csv
- это набор меньших модулей, используемых для чтения /
анализа, преобразования и записи данных CSV из файлов и в файлы.
Мы использовали csv-parse
для чтения файлов CSV и csv-stringify
для
преобразования данных в строки перед их записью в файл с помощью
Node.js.