DevToolBox免费
博客

CSV 转 JSON 转换器完全指南:含代码示例

11 分钟阅读作者 DevToolBox

CSV 转 JSON 是开发者日常面临的最常见数据转换任务之一。无论你是在系统之间迁移数据、构建 API,还是处理电子表格,高效地进行 CSV 转 JSON 转换都是必备技能。CSV(逗号分隔值)和 JSON(JavaScript 对象表示法)是两种最广泛使用的数据交换格式,但它们服务于不同目的且各有优势。本综合指南涵盖了 CSV to JSON 转换器工具、解析算法、JavaScript、Python 和 Bash 代码示例,以及处理边缘情况的最佳实践。如果你需要快速进行在线 CSV 转 JSON 转换,请试用我们的免费工具。

立即试用我们的免费在线 CSV 转 JSON 转换工具。

什么是 CSV(逗号分隔值)?

CSV 即 Comma-Separated Values(逗号分隔值),是一种由 RFC 4180 定义的纯文本文件格式,用于存储表格数据。CSV 文件中的每一行代表一条记录,行中的每个值由逗号(或分号、制表符等其他分隔符)分隔。第一行通常作为表头,定义后续数据的列名。CSV 文件使用 .csv 扩展名和 text/csv MIME 类型。

CSV 格式从计算机早期就开始使用,因其简单性而一直流行。任何文本编辑器、电子表格应用(Excel、Google Sheets、LibreOffice Calc)、数据库工具或编程语言都能读写 CSV。一个典型的 CSV 文件如下:name,age,city\nAlice,30,New York\nBob,25,London。尽管简单,CSV 解析器必须处理几种棘手情况:包含逗号的引号字段、转义双引号、引号内的多行值,以及不同地区的分隔符差异。

何时使用 CSV 或 JSON:CSV 擅长处理扁平的表格数据,如电子表格导出、数据库转储、日志文件和批量数据导入。JSON 更适合层级或嵌套数据结构、API 响应、配置文件和包含混合类型的数据。理解何时使用每种格式以及如何相互转换是数据工程师和 Web 开发者的基础技能。

CSV 与 JSON:详细对比

了解 CSV 和 JSON 的区别有助于你选择正确的格式,并理解 CSV 转 JSON 转换过程中发生了什么:

特性CSVJSON
结构扁平、表格式(行和列)层级式(嵌套对象和数组)
可读性简单数据易读;列多时较难格式化/缩进后可读性好
嵌套原生不支持完全支持(对象中嵌套对象)
数据类型一切都是字符串字符串、数字、布尔值、null、数组、对象
文件大小通常更小(无键重复)更大(每条记录都重复键名)
解析速度非常快(简单分割操作)中等(需要递归下降解析器)
模式隐式(表头行定义列)自描述(每个对象都有键名)
流处理容易逐行处理较难(大文件需类 SAX 解析器)
使用场景电子表格、数据库导出、数据科学API、配置文件、NoSQL 数据库、Web 应用

CSV 转 JSON 的工作原理

CSV to JSON 转换器的处理过程包含以下步骤。理解算法有助于你处理边缘情况并构建更健壮的转换管道:

  1. 读取表头行:解析 CSV 的第一行以提取列名,这些列名将成为每个 JSON 对象的键。例如 name,age,city 产生三个键。
  2. 解析每个数据行:后续行按分隔符(默认逗号)分割,每个值与对应的表头配对形成键值对。
  3. 处理引号字段:用双引号("...")括起来的值被视为单个字段,即使包含逗号、换行符或其他特殊字符。字段内的转义引号使用 ""(两个双引号)。
  4. 检测数据类型:智能转换器会自动检测类型:数字、布尔值、null 值和日期。其他转换器为安全起见将所有值保持为字符串。
  5. 构建 JSON 数组:每行成为一个 JSON 对象,所有对象收集到 JSON 数组中,最终输出为 [{...}, {...}, ...]

转换示例:给定 CSV 输入 name,age,active\nAlice,30,true\nBob,25,false,CSV 转 JSON 的输出为:[{"name":"Alice","age":30,"active":true},{"name":"Bob","age":25,"active":false}]。注意转换器将 3025 检测为数字,将 true/false 检测为布尔值。

CSV 转 JSON 代码示例

JavaScript:CSV 转 JSON

实现 CSV to JSON JavaScript 转换有多种方式。这里介绍原生方法、流行的 Papa Parse 浏览器库和 Node.js 的 csv-parser 模块:

// ===== Native JavaScript: CSV to JSON =====

function csvToJson(csv) {
  const lines = csv.trim().split('\n');
  const headers = lines[0].split(',').map(h => h.trim());
  const result = [];

  for (let i = 1; i < lines.length; i++) {
    const values = lines[i].split(',');
    const obj = {};
    headers.forEach((header, index) => {
      let val = values[index]?.trim() || '';
      // Auto-detect types
      if (val === 'true') val = true;
      else if (val === 'false') val = false;
      else if (val === 'null' || val === '') val = null;
      else if (!isNaN(val) && val !== '') val = Number(val);
      obj[header] = val;
    });
    result.push(obj);
  }
  return result;
}

const csv = `name,age,city,active
Alice,30,New York,true
Bob,25,London,false
Charlie,35,Tokyo,true`;

console.log(JSON.stringify(csvToJson(csv), null, 2));
// [
//   { "name": "Alice", "age": 30, "city": "New York", "active": true },
//   { "name": "Bob", "age": 25, "city": "London", "active": false },
//   { "name": "Charlie", "age": 35, "city": "Tokyo", "active": true }
// ]

// ===== Papa Parse (Browser & Node.js) =====
// npm install papaparse

import Papa from 'papaparse';

// Parse CSV string
const result = Papa.parse(csvString, {
  header: true,         // Use first row as keys
  dynamicTyping: true,  // Auto-detect numbers and booleans
  skipEmptyLines: true, // Ignore blank lines
});

console.log(result.data);   // Array of JSON objects
console.log(result.errors); // Any parsing errors
console.log(result.meta);   // Metadata (delimiter, fields, etc.)

// Parse CSV file (browser)
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (e) => {
  Papa.parse(e.target.files[0], {
    header: true,
    dynamicTyping: true,
    complete: (results) => {
      console.log(results.data); // JSON array
    },
  });
});

// ===== Node.js: csv-parser (streaming) =====
// npm install csv-parser

const csvParser = require('csv-parser');
const fs = require('fs');

const results = [];
fs.createReadStream('data.csv')
  .pipe(csvParser())
  .on('data', (row) => results.push(row))
  .on('end', () => {
    console.log(JSON.stringify(results, null, 2));
  });

Python:CSV 转 JSON

CSV to JSON Python 转换可以使用内置 csv 模块、强大的 pandas 库或简单的 json.dumps。以下是三种方法:

# ===== Python csv module =====
import csv
import json

# CSV string to JSON
csv_string = """name,age,city,active
Alice,30,New York,true
Bob,25,London,false"""

reader = csv.DictReader(csv_string.strip().splitlines())
data = list(reader)
json_output = json.dumps(data, indent=2)
print(json_output)

# CSV file to JSON file
with open('input.csv', 'r', encoding='utf-8') as csv_file:
    reader = csv.DictReader(csv_file)
    data = list(reader)

with open('output.json', 'w', encoding='utf-8') as json_file:
    json.dump(data, json_file, indent=2, ensure_ascii=False)

# ===== pandas (recommended for large datasets) =====
import pandas as pd

# CSV to JSON with pandas
df = pd.read_csv('data.csv')

# Different JSON orientations
print(df.to_json(orient='records', indent=2))  # Array of objects
print(df.to_json(orient='columns', indent=2))  # Object of arrays
print(df.to_json(orient='index', indent=2))     # Object keyed by index

# With type conversion
df['age'] = pd.to_numeric(df['age'], errors='coerce')
df['active'] = df['active'].map({'true': True, 'false': False})

# Save to file
df.to_json('output.json', orient='records', indent=2, force_ascii=False)

# ===== Streaming large CSV files =====
import csv
import json

def csv_to_json_stream(csv_path, json_path, chunk_size=1000):
    """Convert large CSV to JSON using streaming."""
    with open(json_path, 'w') as out:
        out.write('[\n')
        with open(csv_path, 'r', encoding='utf-8') as f:
            reader = csv.DictReader(f)
            first = True
            for row in reader:
                if not first:
                    out.write(',\n')
                json.dump(row, out, ensure_ascii=False)
                first = False
        out.write('\n]')

csv_to_json_stream('large_file.csv', 'output.json')

Bash / 命令行:CSV 转 JSON

命令行 CSV 转 JSON 转换可使用 csvkitmillerjq 甚至 awk 等工具,无需编写完整脚本:

# ===== csvkit: csvjson command =====
# pip install csvkit

# Basic CSV to JSON conversion
csvjson data.csv > output.json

# Indent output for readability
csvjson --indent 2 data.csv > output.json

# Specify a key column (creates object instead of array)
csvjson --key id data.csv > output.json

# ===== miller (mlr): powerful data processing =====
# brew install miller (macOS) or apt install miller (Linux)

# CSV to JSON
mlr --icsv --ojson cat data.csv > output.json

# CSV to JSON with filtering
mlr --icsv --ojson filter '$age > 25' data.csv

# CSV to JSON with field selection
mlr --icsv --ojson cut -f name,city data.csv

# ===== jq + awk: lightweight approach =====
# Convert simple CSV to JSON with awk
awk -F',' 'NR==1{split($0,h);next}
{printf "{";for(i=1;i<=NF;i++)
printf "%s\"%s\":\"%s\"",
(i>1?",":""),h[i],$i;print "}"}' data.csv | jq -s '.'

# ===== Using sed + jq for quick conversion =====
# Convert CSV to JSON (simple, no quoted fields)
head -1 data.csv | tr ',' '\n' > /tmp/headers.txt
tail -n +2 data.csv | while IFS=',' read -r col1 col2 col3; do
  jq -n --arg a "$col1" --arg b "$col2" --arg c "$col3" \
    '{name:$a, age:($b|tonumber), city:$c}'
done | jq -s '.'

专用 CLI 工具:csvjson 和 miller

csvjson(csvkit 的一部分)和 miller(mlr)是专为数据格式转换构建的命令行工具,可优雅地处理边缘情况、编码和大文件:

# ===== csvkit: full suite of CSV tools =====
# pip install csvkit

# View CSV statistics
csvstat data.csv

# Convert CSV to JSON
csvjson data.csv

# Convert Excel to CSV first, then to JSON
in2csv data.xlsx | csvjson > output.json

# Query CSV with SQL syntax, output as JSON
csvsql --query "SELECT name, age FROM data WHERE age > 25" data.csv | csvjson

# ===== miller (mlr): Swiss Army knife for data =====

# CSV to JSON (pretty-printed)
mlr --icsv --ojson --jflatsep '.' cat data.csv

# CSV to JSON with data transformation
mlr --icsv --ojson put '$full_name = $first . " " . $last' data.csv

# CSV to NDJSON (newline-delimited JSON, one object per line)
mlr --icsv --ojsonl cat data.csv

# Convert between any formats
mlr --icsv --ojson cat data.csv       # CSV -> JSON
mlr --ijson --ocsv cat data.json      # JSON -> CSV
mlr --icsv --otsv cat data.csv        # CSV -> TSV
mlr --itsv --ojson cat data.tsv       # TSV -> JSON

JSON 转 CSV(反向过程)

反向过程 JSON 转 CSV 涉及将层级 JSON 数据扁平化为平面表格结构。这比 CSV 转 JSON 更具挑战性,因为 JSON 支持嵌套、数组和混合类型,这些在 CSV 中没有直接对应。

扁平化嵌套对象:当 JSON 对象包含嵌套对象如 {"user":{"name":"Alice","address":{"city":"NYC"}}} 时,JSON 转 CSV 转换器必须使用点号或下划线分隔键名进行扁平化:user.nameuser.address.city。数组可通过创建多行、用分隔符连接值或创建索引列来处理。

以下是 JavaScript 和 Python 中 JSON 转 CSV 的示例:

// ===== JavaScript: JSON to CSV =====

function jsonToCsv(jsonArray) {
  if (!jsonArray.length) return '';

  // Flatten nested objects
  function flatten(obj, prefix = '') {
    return Object.keys(obj).reduce((acc, key) => {
      const fullKey = prefix ? prefix + '.' + key : key;
      if (typeof obj[key] === 'object' && obj[key] !== null && !Array.isArray(obj[key])) {
        Object.assign(acc, flatten(obj[key], fullKey));
      } else if (Array.isArray(obj[key])) {
        acc[fullKey] = obj[key].join('|'); // Join arrays with pipe
      } else {
        acc[fullKey] = obj[key];
      }
      return acc;
    }, {});
  }

  const flatData = jsonArray.map(item => flatten(item));
  const headers = [...new Set(flatData.flatMap(Object.keys))];

  const csvRows = [headers.join(',')];
  for (const row of flatData) {
    const values = headers.map(h => {
      const val = row[h] ?? '';
      // Quote values containing commas, quotes, or newlines
      const str = String(val);
      return str.includes(',') || str.includes('"') || str.includes('\n')
        ? '"' + str.replace(/"/g, '""') + '"'
        : str;
    });
    csvRows.push(values.join(','));
  }
  return csvRows.join('\n');
}

// Example with nested JSON
const data = [
  { name: "Alice", address: { city: "NYC", zip: "10001" }, tags: ["dev", "admin"] },
  { name: "Bob", address: { city: "London", zip: "EC1A" }, tags: ["user"] },
];
console.log(jsonToCsv(data));
// name,address.city,address.zip,tags
// Alice,NYC,10001,dev|admin
// Bob,London,EC1A,user
# ===== Python: JSON to CSV =====
import json
import csv
import pandas as pd

# Method 1: pandas (easiest)
with open('data.json') as f:
    data = json.load(f)

df = pd.json_normalize(data, sep='.')  # Flatten nested objects
df.to_csv('output.csv', index=False)

# Method 2: csv module (manual control)
def json_to_csv(json_data, csv_path):
    """Convert JSON array to CSV, handling nested objects."""
    flat_data = [flatten_dict(item) for item in json_data]
    fieldnames = list(dict.fromkeys(
        key for item in flat_data for key in item.keys()
    ))

    with open(csv_path, 'w', newline='', encoding='utf-8') as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(flat_data)

def flatten_dict(d, parent_key='', sep='.'):
    items = []
    for k, v in d.items():
        new_key = f"{parent_key}{sep}{k}" if parent_key else k
        if isinstance(v, dict):
            items.extend(flatten_dict(v, new_key, sep).items())
        elif isinstance(v, list):
            items.append((new_key, '|'.join(str(i) for i in v)))
        else:
            items.append((new_key, v))
    return dict(items)

CSV 解析的边缘情况处理

一个健壮的 CSV 解析器必须处理简单字符串分割无法管理的众多边缘情况:

UTF-8 BOM(字节顺序标记):某些应用(特别是 Windows 上的 Excel)会在 UTF-8 CSV 文件开头添加 BOM(\uFEFF)。解析器应剥离这个不可见字符,否则第一个列标题会被损坏。

分隔符变化:虽然逗号是标准分隔符,但许多欧洲地区使用分号,因为逗号用作小数分隔符。制表符分隔值(TSV)使用 \t。好的 CSV 解析器应自动检测分隔符或接受参数配置。

缺失值和空字段:CSV 行可能有尾部逗号表示空字段,或中间有缺失值。解析器应将这些保留为空字符串或 null 值,而非移位列。

多行字段:RFC 4180 允许用双引号括起的字段值跨多行。逐行解析器会在这些情况下出错,解析器必须跟踪是否在引号字段内并继续读取直到找到结束引号。

特殊字符和转义:引号字段内的双引号必须通过加倍来转义:"She said ""hello""" 表示值 She said "hello"。反斜杠转义不是标准 CSV,但某些工具会生成它。

不一致的行长度:某些 CSV 文件的行可能比表头有更多或更少的列。弹性解析器应用空值填充短行、截断长行或报告错误。

// Robust CSV parser handling all edge cases
function parseCSV(text, delimiter = ',') {
  // Strip UTF-8 BOM if present
  if (text.charCodeAt(0) === 0xFEFF) {
    text = text.slice(1);
  }

  const rows = [];
  let row = [];
  let field = '';
  let inQuotes = false;

  for (let i = 0; i < text.length; i++) {
    const char = text[i];
    const next = text[i + 1];

    if (inQuotes) {
      if (char === '"' && next === '"') {
        field += '"'; // Escaped quote
        i++;          // Skip next quote
      } else if (char === '"') {
        inQuotes = false; // End of quoted field
      } else {
        field += char; // Regular char inside quotes
      }
    } else {
      if (char === '"') {
        inQuotes = true; // Start quoted field
      } else if (char === delimiter) {
        row.push(field);
        field = '';
      } else if (char === '\n' || (char === '\r' && next === '\n')) {
        row.push(field);
        rows.push(row);
        row = [];
        field = '';
        if (char === '\r') i++; // Skip \n in \r\n
      } else {
        field += char;
      }
    }
  }

  // Push last field and row
  if (field || row.length) {
    row.push(field);
    rows.push(row);
  }

  return rows;
}

CSV 最佳实践

创建、解析或转换 CSV 文件时遵循以下最佳实践,以确保最大兼容性和数据完整性:

始终使用 UTF-8 编码:UTF-8 是文本编码的通用标准。除非绝对必要,否则避免 ASCII、Latin-1 或 Windows-1252。

一致地引用字段:最安全的方法是引用所有字段,不仅仅是包含特殊字符的字段。这可以防止值意外包含逗号、引号或换行符时的解析错误。

包含表头行:始终将表头作为第一行。表头应具有描述性,使用一致的命名约定,避免特殊字符。表头在转换时定义 JSON 键名。

使用一致的分隔符:整个文件坚持使用一个分隔符。对于国际数据,考虑使用制表符,因为它很少出现在字段值中。

流式处理大文件:对于大于可用内存的 CSV 文件,使用流式解析器逐行处理而非加载整个文件。在 Node.js 中使用 csv-parser,Python 中使用 csv.reader()

转换后验证数据:CSV 转 JSON 后验证输出:检查记录数、验证数据类型检测是否正确、确保没有数据丢失,并抽查几条记录与源数据对比。

常见问题

如何将 CSV 转换为 JSON?

要将 CSV 转换为 JSON,首先解析 CSV 表头行获取列名(键),然后解析每一行数据并将值映射到对应的键以创建 JSON 对象,将所有对象收集到 JSON 数组中。你可以手动使用字符串分割,使用 Papa Parse(JavaScript)或 pandas(Python)等库,或使用我们的免费在线 CSV to JSON 转换工具。

CSV 和 JSON 有什么区别?

CSV 是扁平的表格格式,数据以行和列组织,所有值存储为字符串。JSON 是层级格式,支持嵌套对象、数组和多种数据类型。CSV 文件通常更小且解析更快,适合电子表格和批量数据。JSON 更具表达力和自描述性,是 API、配置文件和 Web 应用的标准。

CSV 可以处理嵌套数据吗?

不能,CSV 原生不支持嵌套或层级数据结构。CSV 是扁平格式,只有行和列。要在 CSV 中存储嵌套数据,必须使用扁平化技术,如键的点号表示法、将嵌套值 JSON 编码为字符串、为相关数据创建单独的 CSV 文件,或使用列命名约定来暗示层级关系。

CSV 转 JSON 是开发者、数据工程师和分析师的基础数据转换技能。无论你使用 Papa Parse 等 JavaScript 库、Python 的 pandas、csvkit 和 miller 等命令行工具,还是快速的在线转换器,理解底层的解析规则、边缘情况和最佳实践可确保数据转换准确可靠。收藏本指南以备参考,并使用我们的免费工具进行即时转换。

使用我们的免费在线工具即时转换 CSV 和 JSON。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

📊CSV ↔ JSON Converter{ }JSON FormatterY{}JSON ↔ YAML Converter<>XML Formatter

相关文章

JSON vs YAML vs TOML:你应该用哪种配置格式?

比较 JSON、YAML 和 TOML 配置格式,了解语法、特性和优缺点,选择适合你项目的格式。

JSON 格式化与验证:在线美化、修复 JSON 完全指南

免费在线 JSON 格式化和验证工具。美化 JSON、查找语法错误,附 JavaScript 和 Python 代码示例。

JSON 转 TypeScript:完整指南与示例

学习如何自动将 JSON 数据转换为 TypeScript 接口。涵盖嵌套对象、数组、可选字段和最佳实践。