Работа с CSV в TypeScript: библиотеки и примеры кода

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Работа с CSV в TypeScript: полное руководство

CSV (Comma-Separated Values) — один из самых популярных форматов для обмена табличными данными. В TypeScript (и JavaScript) существует несколько мощных библиотек для парсинга, генерации и обработки CSV-файлов. В этой статье мы рассмотрим основные инструменты, их возможности и приведём практические примеры.

Зачем использовать библиотеки для CSV?

Встроенные средства JavaScript (например, split(',')) не учитывают сложные случаи:

  • Экранированные кавычки и запятые внутри полей
  • Разные разделители (точка с запятой, табуляция)
  • Разные кодировки и BOM
  • Многострочные значения
  • Разные типы окончания строк (CRLF, LF)

Профессиональные библиотеки решают все эти проблемы и предоставляют удобный API для работы с данными.

1. csv-parse — парсинг CSV в Node.js и браузере

csv-parse — это часть экосистемы csv.js, одна из самых популярных библиотек для парсинга. Она работает как в Node.js, так и в браузере (через bundler).

Установка

npm install csv-parse

Пример использования с TypeScript

import { parse } from 'csv-parse/sync';
import { readFileSync } from 'fs';

interface User {
    id: number;
    name: string;
    email: string;
}

const csvData = readFileSync('users.csv', 'utf-8');
const records: User[] = parse(csvData, {
    columns: true,          // первая строка — заголовки
    skip_empty_lines: true,
    delimiter: ',',
    cast: (value, context) => {
        if (context.column === 'id') return parseInt(value, 10);
        return value;
    }
});

console.log(records);

2. PapaParse — универсальный парсер для браузера и Node.js

PapaParse — это библиотека с отличной поддержкой больших файлов (потоковая обработка), автоматическим определением разделителя и широкими возможностями конфигурации.

Установка

npm install papaparse

Пример с типизацией результатов

import Papa from 'papaparse';

interface Product {
    sku: string;
    price: number;
    quantity: number;
}

const csvString = `sku,price,quantity
ABC-001,29.99,100
ABC-002,49.50,50`;

const result = Papa.parse<Product>(csvString, {
    header: true,
    dynamicTyping: true,  // автоматическое преобразование типов
    skipEmptyLines: true
});

if (result.errors.length > 0) {
    console.error('Ошибки парсинга:', result.errors);
} else {
    result.data.forEach(product => {
        console.log(`Товар ${product.sku}: ${product.price} руб.`);
    });
}

3. csv-stringify — генерация CSV из данных

Для обратной задачи — создания CSV из массивов объектов — используйте csv-stringify. Он также входит в экосистему csv.js.

Установка

npm install csv-stringify

Пример генерации CSV

import { stringify } from 'csv-stringify/sync';
import { writeFileSync } from 'fs';

interface Order {
    orderId: number;
    customer: string;
    total: number;
}

const orders: Order[] = [
    { orderId: 1001, customer: 'Иван Петров', total: 1500.50 },
    { orderId: 1002, customer: 'Мария Сидорова', total: 2300.00 },
    { orderId: 1003, customer: 'Алексей Иванов', total: 890.75 }
];

const csvOutput = stringify(orders, {
    header: true,
    columns: ['orderId', 'customer', 'total']
});

writeFileSync('orders.csv', csvOutput, 'utf-8');
console.log('CSV файл создан успешно');

4. Обработка ошибок и валидация данных

При работе с CSV важно корректно обрабатывать ошибки. Рассмотрим пример с проверкой данных:

import Papa from 'papaparse';

interface ValidatedRow {
    isValid: boolean;
    errors: string[];
    data: Record<string, any>;
}

function validateCSV(csvString: string): ValidatedRow[] {
    const result = Papa.parse(csvString, { header: true, skipEmptyLines: true });
    
    return result.data.map((row: any) => {
        const errors: string[] = [];
        
        if (!row.email || !row.email.includes('@')) {
            errors.push('Некорректный email');
        }
        if (!row.age || isNaN(Number(row.age)) || Number(row.age) < 0) {
            errors.push('Некорректный возраст');
        }
        
        return {
            isValid: errors.length === 0,
            errors,
            data: row
        };
    });
}

// Использование
const csvSample = `name,                    

Рекомендаций