CSV 转 JSON:实用指南
为什么要将 CSV 转换为 JSON?
CSV(逗号分隔值)和 JSON(JavaScript 对象表示法)是两种最常见的数据格式,但它们的用途不同。CSV 适合电子表格和表格数据,而 JSON 擅长表示结构化的层次数据。在数据处理、API 开发和配置管理中,两者之间的转换是一项常见任务。
CSV 与 JSON:快速对比
| 特性 | CSV | JSON |
|---|---|---|
| 结构 | 扁平、表格状 | 层次化、可嵌套 |
| 数据类型 | 全部为字符串 | 字符串、数字、布尔值、null |
| 表头 | 第一行(可选) | 每个对象中的键 |
| 嵌套 | 原生不支持 | 完全支持 |
| 可读性 | 好(小数据集) | 好(尤其是格式化后) |
| 文件大小 | 较小 | 较大(重复的键) |
| 解析速度 | 较快 | 稍慢 |
基本转换
以下是一个简单的 CSV 文件及其对应的 JSON:
CSV:
name,age,city
Alice,30,New York
Bob,25,San Francisco
Charlie,35,Chicago
JSON:
[
{ "name": "Alice", "age": 30, "city": "New York" },
{ "name": "Bob", "age": 25, "city": "San Francisco" },
{ "name": "Charlie", "age": 35, "city": "Chicago" }
]
注意在 JSON 中,age 值可以是真正的数字而非字符串——JSON 保留数据类型,而 CSV 将所有内容视为文本。
编写 CSV 转 JSON 转换器
简单实现
function csvToJson(csv) {
const lines = csv.trim().split('\n');
const headers = lines[0].split(',');
return lines.slice(1).map(line => {
const values = line.split(',');
const obj = {};
headers.forEach((header, index) => {
obj[header.trim()] = values[index]?.trim() || '';
});
return obj;
});
}
const csv = `name,age,city
Alice,30,New York
Bob,25,San Francisco`;
console.log(JSON.stringify(csvToJson(csv), null, 2));
这在简单情况下可以工作,但现实中的 CSV 数据很少这么干净。
处理常见的 CSV 陷阱
1. 包含逗号的引号字段
包含逗号的 CSV 字段必须用引号包裹:
name,description
"Smith, John","A developer, designer"
简单的 split(',') 会破坏这种数据。你需要一个正确的 CSV 解析器:
function parseCSVLine(line) {
const result = [];
let current = '';
let inQuotes = false;
for (let i = 0; i < line.length; i++) {
const char = line[i];
if (char === '"') {
if (inQuotes && line[i + 1] === '"') {
current += '"';
i++; // 跳过转义引号
} else {
inQuotes = !inQuotes;
}
} else if (char === ',' && !inQuotes) {
result.push(current);
current = '';
} else {
current += char;
}
}
result.push(current);
return result;
}
2. 不同的分隔符
并非所有 CSV 文件都使用逗号。制表符分隔值(TSV)和分号分隔文件也很常见,尤其是在使用逗号作为小数点的欧洲地区。
function csvToJson(csv, delimiter = ',') {
const lines = csv.trim().split('\n');
const headers = parseCSVLine(lines[0], delimiter);
return lines.slice(1).map(line => {
const values = parseCSVLine(line, delimiter);
const obj = {};
headers.forEach((header, index) => {
obj[header.trim()] = values[index]?.trim() || '';
});
return obj;
});
}
// 制表符分隔数据
const tsvData = csvToJson(tsvContent, '\t');
// 分号分隔数据
const csvData = csvToJson(csvContent, ';');
3. 类型推断
CSV 值都是字符串,但你通常希望 JSON 中有数字、布尔值或 null:
function inferType(value) {
if (value === '' || value === 'null' || value === 'NULL') return null;
if (value === 'true' || value === 'TRUE') return true;
if (value === 'false' || value === 'FALSE') return false;
if (!isNaN(value) && value.trim() !== '') return Number(value);
return value;
}
// 在转换过程中应用类型推断
headers.forEach((header, index) => {
obj[header.trim()] = inferType(values[index]?.trim() || '');
});
处理嵌套数据
CSV 本质上是扁平的,但有时你需要嵌套的 JSON 结构。一种常见的约定是在表头中使用点号表示法:
user.name,user.email,address.city,address.zip
Alice,alice@example.com,New York,10001
转换为:
[
{
"user": { "name": "Alice", "email": "alice@example.com" },
"address": { "city": "New York", "zip": 10001 }
}
]
function setNestedValue(obj, path, value) {
const keys = path.split('.');
let current = obj;
for (let i = 0; i < keys.length - 1; i++) {
if (!current[keys[i]]) current[keys[i]] = {};
current = current[keys[i]];
}
current[keys[keys.length - 1]] = value;
}
大文件处理建议
对于大型 CSV 文件(数百万行),请注意以下几点:
- 流式处理:不要将整个文件加载到内存中,逐行处理
- 批量写入:分块写入 JSON 输出,而不是构建一个巨大的数组
- 内存占用:100 MB 的 CSV 文件转换为 JSON 后可能扩展到 200+ MB,因为键名会重复
// 流式处理方式(Node.js)
const readline = require('readline');
const fs = require('fs');
async function convertLargeCSV(inputPath, outputPath) {
const stream = fs.createReadStream(inputPath);
const rl = readline.createInterface({ input: stream });
const output = fs.createWriteStream(outputPath);
output.write('[\n');
let headers = null;
let first = true;
for await (const line of rl) {
if (!headers) {
headers = line.split(',');
continue;
}
const values = line.split(',');
const obj = {};
headers.forEach((h, i) => obj[h] = values[i]);
if (!first) output.write(',\n');
output.write(JSON.stringify(obj));
first = false;
}
output.write('\n]');
}
使用 CodeKit 工具
无需编写代码即可快速转换,使用这些 CodeKit 工具:
- CSV 转 JSON:粘贴 CSV 数据即可获得即时 JSON 输出,支持自定义分隔符和类型推断
- JSON 格式化:格式化和验证 JSON 输出,提高可读性
两个工具都完全在浏览器中运行——数据不会发送到任何服务器。
总结
将 CSV 转换为 JSON 是一项看似简单但有许多边界情况的任务。引号字段、不同分隔符、类型推断和嵌套结构都需要仔细处理。无论你是自己编写转换器还是使用工具,理解这些细节都能帮助你避免数据损坏,构建更健壮的数据处理流程。
准备好转换数据了吗?试试 CodeKit 上的 CSV 转 JSON 转换器 和 JSON 格式化工具,即时在浏览器中完成转换。