Skip to content

入门

本篇讲 Papa Parse 5.5.4 的最小可用知识:装包 → 解析字符串 → 表头与类型转换 → 反解析回 CSV → 解析用户上传文件。核心 API 只有 Papa.parse(CSV→JS)和 Papa.unparse(JS→CSV)两个。

速查

  • 安装:npm i papaparse;TypeScript 另装 npm i -D @types/papaparse(主包不含 .d.ts
  • 解析字符串:const r = Papa.parse(text){ data, errors, meta }(同步返回)
  • 首行作表头:Papa.parse(text, { header: true }) → 每行变对象
  • 自动转类型:{ dynamicTyping: true } → 数字、布尔、空值与完整 ISO 日期转型
  • 跳空行:{ skipEmptyLines: true }(或 'greedy' 连只含空白的行也跳)
  • 反解析:Papa.unparse(arrayOrObjects) → CSV 字符串
  • 解析 File:Papa.parse(file, { complete: res => ... })(异步回调)
  • 拉远程:Papa.parse(url, { download: true, complete: ... })
  • ⚠️ 默认所有值都是字符串,要数字需开 dynamicTyping
  • ⚠️ 不要text.split(',') 手撕 CSV(引号内逗号/换行会被切错)

一、PapaParse 是什么

官方一句话定位:「The powerful, in-browser CSV parser」。两个核心方法:

  1. Papa.parse(input, config):把 CSV 解析成 JS 数据。
  2. Papa.unparse(data, config):把 JS 数据反解析回 CSV 字符串。

它的价值是正确:CSV 允许「引号字段内含逗号、换行,引号双写转义」,简单 split 处理不了,PapaParse 用状态机正确解析。

bash
npm i papaparse
ts
import Papa from "papaparse";

二、解析一段 CSV 字符串

传字符串,且不开 step / chunk / worker / download 时,Papa.parse 同步返回结果对象:

ts
const csv = `name,age
Ada,30
Bob,25`;

const result = Papa.parse(csv);
// result.data   → [["name","age"], ["Ada","30"], ["Bob","25"]]
// result.errors → []
// result.meta   → { delimiter: ",", linebreak: "\n", aborted: false, ... }

默认两件事

① 默认 header:false,每行是数组,整个 data 是「数组的数组」; ② 默认所有值都是字符串"30" 而非 30)。

三、把首行当表头(header)

header: true,首行作字段名,每行解析成对象,字段名记录在 meta.fields

ts
const result = Papa.parse(csv, { header: true });
// result.data        → [{ name: "Ada", age: "30" }, { name: "Bob", age: "25" }]
// result.meta.fields → ["name", "age"]

四、自动类型转换(dynamicTyping)

dynamicTyping: true 把「看起来是数字/布尔」的字段转成真正的类型:

ts
const result = Papa.parse(csv, { header: true, dynamicTyping: true });
// result.data → [{ name: "Ada", age: 30 }, { name: "Bob", age: 25 }]  // age 现在是 number

三个注意

① 完整 ISO 8601 时间戳会转成 Date,空字符串会转成 null; ② 超出安全整数边界的数为保精度会保持字符串; ③ 007 这类前导零标识符会变成 7——这类列要用对象 / 函数形式关闭转型(见进阶篇)。

五、清理空行(skipEmptyLines)

ts
Papa.parse(csv, { skipEmptyLines: true });    // 跳过完全空的行
Papa.parse(csv, { skipEmptyLines: "greedy" }); // 连「只剩空白」的行(如 `,,, `)也跳

六、反解析:JS → CSV(unparse)

ts
// 对象数组(默认带表头)
Papa.unparse([
  { name: "Ada", age: 30 },
  { name: "Bob", age: 25 },
]);
// → "name,age\r\nAda,30\r\nBob,25"

// 数组的数组
Papa.unparse([
  ["name", "age"],
  ["Ada", 30],
]);

// 不要表头
Papa.unparse(rows, { header: false });

对象数组的 unparse 默认输出表头,换行默认 \r\n。数组的数组由数据本身决定首行,header 选项会被忽略;含分隔符、引号或换行的字段会自动加引号并转义。

七、解析用户上传的文件(File)

File 对象直接传给 Papa.parse,结果异步走回调(无需先 FileReader 读文本):

ts
// <input type="file" id="csv">
document.getElementById("csv")!.addEventListener("change", (e) => {
  const file = (e.target as HTMLInputElement).files![0];
  Papa.parse(file, {
    header: true,
    dynamicTyping: true,
    skipEmptyLines: true,
    complete: (res) => {
      console.log("行数:", res.data.length, "错误:", res.errors);
    },
    error: (err) => console.error("读取失败:", err),
  });
});

八、为什么不能 split(',') 手撕

ts
const line = '"Hello, World",foo';
line.split(","); // ❌ ['"Hello', ' World"', 'foo']  —— 引号内逗号被错切

Papa.parse(line).data[0]; // ✅ ["Hello, World", "foo"]  —— 正确识别为两列

CSV 允许引号字段内含逗号、换行,还有双写引号转义;split 全不懂。永远用解析器,别手撕。


掌握基础后,进入 参考:全部 config 选项 / ParseResult / 常量速查;或直接看 指南 · 基础 学流式与 Worker。