PapaParse CSV
灵感:能力工具箱 papaparse(pkg: papaparse)。
> 小四原创:选文件 → 解析 → 表格预览 → 表头映射到客户字段;大文件用 worker/分片提示。
何时使用
- 批量导入客户/线索前先看 CSV
- Excel 另存 CSV 后前端解析
- 表头与系统字段不一致要对齐
硬约束
- 使用
papaparse;header: true默认开(无表头则关)。 - 编码:优先 UTF-8;乱码时提示用户另存 UTF-8 或尝试
encoding。 - 预览默认前 50 行;全量导入需二次确认。
- 空文件/无行给出中文错误。
- 实现要点注释标 小四原创。
推荐实现
import Papa from 'papaparse'
export type CsvPreview = {
fields: string[]
rows: Record<string, string>[]
errors: string[]
}
// 小四原创:解析 File/文本为预览
export function parseCsvFile(file: File): Promise<CsvPreview> {
return new Promise((resolve) => {
Papa.parse(file, {
header: true,
skipEmptyLines: true,
complete: (res) => {
const fields = res.meta.fields || []
const rows = (res.data as Record<string, string>[]).slice(0, 50)
const errors = (res.errors || []).slice(0, 5).map((e) => e.message)
if (!fields.length && !rows.length) {
resolve({ fields: [], rows: [], errors: ['CSV 为空或无法解析'] })
return
}
resolve({ fields, rows, errors })
},
error: (err) => resolve({ fields: [], rows: [], errors: [String(err)] }),
})
})
}
// 小四原创:表头映射
export function mapRows(
rows: Record<string, string>[],
mapping: Record<string, string>, // csvHeader -> fieldKey
) {
return rows.map((r) => {
const out: Record<string, string> = {}
for (const [header, key] of Object.entries(mapping)) {
if (key) out[key] = r[header] ?? ''
}
return out
})
}
Agent 步骤
- 文件选择 +
parseCsvFile。 - 展示 fields 与预览表;配置映射(公司/联系人/手机…)。
- 确认后才写入业务库;可接 Zod/Yup 行校验。
- 自测:含中文表头 UTF-8 CSV;空文件。
不要做
- 静默导入上万行不提示内存风险。
- 把 xlsx 二进制当 CSV 硬解(应先转 CSV 或用专门库)。
附加
- README.md · reference.md · templates/usage.md