CSV и JSON — два самых распространённых формата для хранения и обмена данными. CSV идеален для таблиц и электронных таблиц, JSON — для API и веб-приложений. Понимание обоих форматов и умение конвертировать между ними критически важно для разработчиков. В этой статье разберём формат каждого типа, алгоритмы конвертации и практические примеры на JavaScript и Python.
Формат CSV: структура и правила
CSV (Comma-Separated Values) — текстовый формат для представления табличных данных. Каждая строка — это запись, поля разделены специальным символом-разделителем.
Разделители
Стандартный разделитель — запятая, но в разных регионах и приложениях используются:
- Запятая — стандарт в англоязычных странах
- Точка с запятой — распространён в Европе, где запятая служит десятичным разделителем
- Табуляция — TSV (Tab-Separated Values), часто для экспорта из баз данных
- Вертикальная черта — альтернатива, когда в данных встречаются запятые и точки с запятой
name,email,age
Иван Петров,ivan@example.com,30
Мария Сидорова,maria@example.com,25
Правила кавычек и RFC 4180
Спецификация RFC 4180 описывает стандарт CSV:
- Поля с разделителями, кавычками или переносами строк заключаются в двойные кавычки
- Кавычки внутри поля экранируются удвоением:
"He said ""Hello""" - Первая строка может содержать заголовки (имена колонок)
id,name,description
1,"Иванов, Иван","Строка с ""кавычками"""
2,"Петрова, Мария","Обычное поле"
Проблемы совместимости
Excel и другие табличные редакторы могут интерпретировать CSV по-своему: менять кодировку, разделители и правила кавычек. При экспорте из Excel в CSV часто используется точка с запятой в локальных настройках с запятой как десятичным разделителем. При импорте в другие системы важно явно указывать разделитель и кодировку, иначе данные могут отображаться некорректно.
Формат JSON: структура и вложенность
JSON (JavaScript Object Notation) — формат обмена данными на основе пар ключ-значение. Поддерживает массивы, объекты и вложенные структуры.
Массивы объектов
Типичная структура для табличных данных — массив объектов с одинаковыми ключами:
[
{"name": "Иван Петров", "email": "ivan@example.com", "age": 30},
{"name": "Мария Сидорова", "email": "maria@example.com", "age": 25}
]
Вложенные данные
JSON позволяет хранить вложенные объекты и массивы, что невозможно напрямую в плоском CSV:
{
"user": {
"name": "Иван",
"address": {
"city": "Москва",
"street": "Тверская"
},
"tags": ["admin", "editor"]
}
}
CSV vs JSON: когда что использовать
| Критерий | CSV | JSON |
|---|---|---|
| Читаемость | Удобен в Excel, текстовых редакторах | Удобен в коде, API |
| Структура | Только плоские таблицы | Вложенные объекты и массивы |
| Размер | Обычно компактнее для таблиц | Больше из-за ключей и синтаксиса |
| Типичное применение | Экспорт/импорт, отчёты, аналитика | API, конфигурации, веб-приложения |
| Стандартизация | RFC 4180, но много вариаций | Строгий стандарт ECMA-404 |
CSV подходит для работы в Excel, импорта в CRM, отчётов и простых таблиц. JSON — для REST API, конфигураций, обмена данными между сервисами и хранения структурированных данных в приложениях. При выборе формата учитывайте целевую систему: если данные будут открываться в Excel или импортироваться в 1С — предпочтите CSV; если данные идут в веб-приложение или мобильное приложение — JSON обычно удобнее.
Конвертация CSV в JSON
Алгоритм
- Прочитать файл построчно
- Определить разделитель (запятая, точка с запятой, табуляция)
- Первую строку использовать как заголовки (ключи)
- Для каждой следующей строки: разобрать поля с учётом кавычек, собрать объект
- Добавить объект в массив
Обработка краевых случаев
- Пустые поля →
nullили пустая строка - Кавычки внутри полей
- Переносы строк внутри кавычек
- Разные кодировки (UTF-8, UTF-8 BOM, Windows-1251)
JavaScript: Papa Parse
Библиотека Papa Parse — надёжный парсер CSV для браузера и Node.js:
const Papa = require('papaparse');
const csvString = `name,email,age
Иван Петров,ivan@example.com,30
Мария Сидорова,maria@example.com,25`;
const result = Papa.parse(csvString, {
header: true,
skipEmptyLines: true,
encoding: 'UTF-8'
});
console.log(JSON.stringify(result.data, null, 2));
// [
// {"name": "Иван Петров", "email": "ivan@example.com", "age": "30"},
// {"name": "Мария Сидорова", "email": "maria@example.com", "age": "25"}
// ]
JavaScript: ручной парсинг
Для простых CSV без сложных кавычек можно обойтись без библиотек:
function csvToJson(csv) {
const lines = csv.trim().split('\n');
const headers = lines[0].split(',');
return lines.slice(1).map(line => {
const values = line.split(',');
return headers.reduce((obj, header, i) => {
obj[header.trim()] = values[i]?.trim() || '';
return obj;
}, {});
});
}
Такой подход не учитывает кавычки и вложенные запятые — для продакшена лучше использовать Papa Parse. При парсинге CSV с кавычками важно обрабатывать состояние «внутри кавычек»: символы запятой и переноса строки внутри кавычек не должны разбивать поле. Реализация полноценного парсера с учётом RFC 4180 требует конечного автомата или рекурсивного спуска.
Python: модуль csv
Стандартный модуль csv корректно обрабатывает RFC 4180:
import csv
import json
def csv_to_json(csv_string):
reader = csv.DictReader(csv_string.splitlines())
return list(reader)
csv_data = """name,email,age
Иван Петров,ivan@example.com,30
Мария Сидорова,maria@example.com,25"""
result = csv_to_json(csv_data)
print(json.dumps(result, ensure_ascii=False, indent=2))
Python: pandas
Для больших файлов и аналитики удобен pandas:
import pandas as pd
df = pd.read_csv('data.csv', encoding='utf-8-sig')
json_data = df.to_json(orient='records', force_ascii=False)
Параметр encoding='utf-8-sig' обрабатывает BOM в начале файла. Для файлов с точкой с запятой в качестве разделителя укажите sep=';'. Если заголовки отсутствуют, передайте header=None и задайте имена колонок через параметр names.
Конвертация JSON в CSV
Сглаживание вложенных объектов
Вложенные объекты нужно «развернуть» в плоскую структуру. Варианты: объединить ключи через точку (address.city) или сохранить вложенность в виде строки.
function flattenObject(obj, prefix = '') {
return Object.keys(obj).reduce((acc, key) => {
const value = obj[key];
const newKey = prefix ? `${prefix}.${key}` : key;
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
Object.assign(acc, flattenObject(value, newKey));
} else if (Array.isArray(value)) {
acc[newKey] = value.join('; ');
} else {
acc[newKey] = value;
}
return acc;
}, {});
}
Обработка массивов
Массивы можно преобразовать в строку (через запятую или точку с запятой) или развернуть в отдельные строки CSV. Выбор зависит от задачи. Например, для тегов пользователя ["admin", "editor"] можно сохранить как "admin; editor" в одной ячейке. Для массивов объектов (например, список заказов в профиле пользователя) потребуется либо денормализация в несколько строк, либо сериализация в JSON-строку внутри ячейки — последний вариант усложняет последующую работу с данными в Excel.
JavaScript: Papa Parse (обратная конвертация)
const jsonData = [
{ name: 'Иван Петров', email: 'ivan@example.com', age: 30 },
{ name: 'Мария Сидорова', email: 'maria@example.com', age: 25 }
];
const csv = Papa.unparse(jsonData);
console.log(csv);
// name,email,age
// Иван Петров,ivan@example.com,30
// Мария Сидорова,maria@example.com,25
Python: csv и pandas
import json
import csv
with open('data.json', 'r', encoding='utf-8') as f:
data = json.load(f)
if data:
with open('output.csv', 'w', encoding='utf-8', newline='') as f:
writer = csv.DictWriter(f, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
Через pandas:
import pandas as pd
df = pd.read_json('data.json')
df.to_csv('output.csv', index=False, encoding='utf-8-sig')
Типичные проблемы и решения
Кодировка и BOM
Excel при сохранении CSV в UTF-8 добавляет BOM (Byte Order Mark) в начало файла. В Python используйте encoding='utf-8-sig', в JavaScript — проверку на \uFEFF в начале строки.
Совместимость с Excel
Для корректного отображения в Excel: UTF-8 с BOM, точка с запятой как разделитель в локальных настройках с запятой как десятичным разделителем. Некоторые системы ожидают \r\n в конце строк.
Большие файлы
При объёмах в гигабайты не загружайте весь файл в память. Используйте потоковую обработку: в Node.js — fs.createReadStream и потоковый парсер, в Python — итерацию по строкам или pandas с chunksize. Papa Parse поддерживает потоковый режим через Papa.parse(stream, { stream: true }). В pandas укажите chunksize=10000 при вызове read_csv, чтобы обрабатывать файл порциями. Это снижает потребление памяти и позволяет обрабатывать файлы, превышающие объём RAM.
Специальные символы
В CSV экранируйте кавычки удвоением. В JSON экранируйте ", \, переносы строк и табуляцию. При конвертации следите за корректной обработкой Unicode. Кириллица и другие не-ASCII символы должны сохраняться без искажений — всегда указывайте кодировку UTF-8 при чтении и записи файлов. В Python используйте параметр encoding='utf-8' при открытии файлов; в Node.js по умолчанию используется UTF-8, но при работе с буферами проверяйте кодировку.
Выбор библиотек и инструментов
При работе с CSV в JavaScript Papa Parse остаётся наиболее надёжным решением: поддерживает потоковую обработку, автоматическое определение разделителя и корректную обработку кавычек. Альтернативы — csv-parse и fast-csv — подходят для специфичных сценариев. В Python стандартный модуль csv достаточен для большинства задач; pandas добавляет возможности фильтрации, агрегации и работы с типами данных. Для конвертации JSON в CSV с вложенными структурами рассмотрите библиотеку flatten-json в Python или собственную функцию сглаживания в JavaScript. При выборе стратегии сглаживания учитывайте, как данные будут использоваться: для импорта в Excel достаточно одной строки на объект с плоскими ключами; для последующей загрузки обратно в JSON может потребоваться соглашение об именовании вложенных полей (например, user.address.city).
Заключение
Конвертация между CSV и JSON — частая задача при интеграции систем, импорте данных и работе с API. Выбор формата зависит от контекста: таблицы и отчёты — CSV, API и веб-приложения — JSON. Для надёжной конвертации учитывайте кодировку, разделители, кавычки и размер данных.
Для быстрой конвертации без написания кода можно использовать онлайн-сервис CSV в JSON, который поддерживает различные разделители и кодировки. Сервис подходит для разовых преобразований, проверки формата данных и быстрого экспорта таблиц в JSON для использования в API или конфигурациях.