Работа с CSV в TypeScript: полное руководство
CSV (Comma-Separated Values) — один из самых распространённых форматов для обмена табличными данными. В экосистеме TypeScript доступно несколько мощных библиотек, которые позволяют читать, писать и преобразовывать CSV-файлы с полной поддержкой типов. В этой статье мы разберём основные инструменты, их установку и практические примеры.
Популярные библиотеки для работы с CSV
Наиболее часто используемые библиотеки в TypeScript/Node.js среде:
csv-parse— часть набораcsv, надёжный парсер с поддержкой потоковpapaparse— универсальный парсер для браузера и Node.jscsv-stringify— генератор CSV из массивов/объектовcsvtojson— конвертер CSV в JSON с типизацией
Установка и настройка
Для проектов на TypeScript установка производится через npm или yarn:
npm install csv-parse csv-stringify papaparse @types/papaparse
Если вы используете csv-parse, дополнительные типы не требуются — библиотека имеет встроенную поддержку TypeScript.
Пример 1: Парсинг CSV с помощью csv-parse
Библиотека csv-parse отлично подходит для работы с большими файлами благодаря stream API. Рассмотрим базовый пример:
import { parse } from 'csv-parse/sync';
import * as fs from 'fs';
interface User {
id: number;
name: string;
email: string;
age: number;
}
const csvData = fs.readFileSync('users.csv', 'utf-8');
const records: User[] = parse(csvData, {
columns: true, // первая строка — заголовки
skip_empty_lines: true,
delimiter: ',',
cast: (value, context) => {
if (context.column === 'id' || context.column === 'age') {
return Number(value);
}
return value;
}
});
console.log(records);
// [
// { id: 1, name: 'Иван', email: 'ivan@example.com', age: 30 },
// { id: 2, name: 'Мария', email: 'maria@example.com', age: 25 }
// ]
Пример 2: Генерация CSV с типизацией
Для создания CSV-файлов используйте csv-stringify. Определим тип данных и сгенерируем строку:
import { stringify } from 'csv-stringify/sync';
interface Product {
productId: string;
name: string;
price: number;
inStock: boolean;
}
const products: Product[] = [
{ productId: 'P001', name: 'Ноутбук', price: 75000, inStock: true },
{ productId: 'P002', name: 'Мышь', price: 1500, inStock: false },
{ productId: 'P003', name: 'Клавиатура', price: 3500, inStock: true }
];
const csvOutput = stringify(products, {
header: true,
columns: ['productId', 'name', 'price', 'inStock']
});
console.log(csvOutput);
// productId,name,price,inStock
// P001,Ноутбук,75000,true
// P002,Мышь,1500,false
// P003,Клавиатура,3500,true
Пример 3: Использование PapaParse в браузере
PapaParse идеален для клиентской обработки CSV. Пример с загрузкой файла через input:
import Papa from 'papaparse';
interface Transaction {
date: string;
amount: number;
category: string;
description: string;
}
const fileInput = document.getElementById('csvInput') as HTMLInputElement;
fileInput.addEventListener('change', (event) => {
const file = (event.target as HTMLInputElement).files?.[0];
if (!file) return;
Papa.parse<Transaction>(file, {
header: true,
dynamicTyping: true, // автоматическое преобразование типов
skipEmptyLines: true,
complete: (result) => {
console.log('Парсинг завершён:', result.data);
// result.data — массив объектов Transaction
},
error: (error) => {
console.error('Ошибка парсинга:', error);
}
});
});
Пример 4: Обработка больших файлов потоком
Для файлов размером более 100 МБ используйте потоковую обработку с csv-parse:
import { createReadStream } from 'fs';
import { parse } from 'csv-parse';
import { Transform } from 'stream';
interface LogEntry {
timestamp: string;
level: string;
message: string;
}
const parser = parse({
columns: true,
delimiter: ',',
relax_column_count: true
});
const transformer = new Transform({
objectMode: true,
transform(record: LogEntry, encoding, callback) {
// Преобразование данных
record.level = record.level.to