You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js读取CSV的Account ID调用API合并数据生成新CSV求助

Node.js CSV与API数据合并实现方案

前置依赖

需安装第三方CSV处理工具,Node.js 18+ 可使用原生fetch无需额外安装请求库:

npm install csv-parser csv-writer

完整实现代码

const fs = require('fs');
const csv = require('csv-parser');
const createCsvWriter = require('csv-writer').createObjectCsvWriter;

// 配置项
const INPUT_CSV_PATH = './input.csv';
const OUTPUT_CSV_PATH = './output.csv';
const API_BASE = 'https://company.callout.io/v1/accounts/';
const CONCURRENT_LIMIT = 5; // 并发请求数,避免触发API限流

// 并发控制工具函数
const limitConcurrency = (limit, tasks) => {
  const executing = new Set();
  return Promise.all(tasks.map(task => {
    while (executing.size >= limit) {
      return Promise.race(executing).then(() => limitConcurrency(limit, [task]));
    }
    const promise = Promise.resolve().then(task);
    executing.add(promise);
    promise.finally(() => executing.delete(promise));
    return promise;
  }));
};

(async () => {
  // 1. 读取CSV并自动识别表头
  const rows = [];
  let headers = [];
  await new Promise((resolve, reject) => {
    fs.createReadStream(INPUT_CSV_PATH)
      .pipe(csv())
      .on('headers', (headerList) => {
        headers = headerList;
      })
      .on('data', (row) => rows.push(row))
      .on('end', resolve)
      .on('error', reject);
  });

  // 2. 自动识别Account ID列,无需硬编码列名
  const accountIdKey = headers.find(h => 
    h.toLowerCase().replace(/\s/g, '').includes('accountid')
  );
  if (!accountIdKey) throw new Error('未在CSV中找到Account ID列');

  // 3. 批量请求API合并数据
  await limitConcurrency(CONCURRENT_LIMIT, rows.map(row => async () => {
    const accountId = row[accountIdKey]?.toString().trim();
    // 兼容空Account ID、无效ID的情况
    if (!accountId) {
      row.Status = '';
      row['Status Set On'] = '';
      return;
    }
    try {
      const res = await fetch(`${API_BASE}${encodeURIComponent(accountId)}`);
      if (!res.ok) throw new Error('API请求失败');
      const apiData = await res.json();
      row.Status = apiData.status || '';
      row['Status Set On'] = apiData.created_on || '';
    } catch (e) {
      // API请求失败时留空,不中断整体流程
      row.Status = '';
      row['Status Set On'] = '';
    }
  }));

  // 4. 输出新CSV,动态生成表头不硬编码原有列
  const csvWriter = createCsvWriter({
    path: OUTPUT_CSV_PATH,
    header: [
      ...headers.map(h => ({id: h, title: h})),
      {id: 'Status', title: 'Status'},
      {id: 'Status Set On', title: 'Status Set On'}
    ]
  });
  await csvWriter.writeRecords(rows);
  console.log('CSV生成完成');
})();

关键兼容逻辑说明

  • 列名适配:自动识别含account+id关键字的列作为账号列,忽略大小写、空格差异,无需硬编码原有CSV列名
  • 异常兼容:
    • 空账号、负账号、特殊字符账号自动处理,空值直接跳过API请求
    • API请求超时、返回错误、字段缺失时新增列自动填充空值,不会中断整体导出流程
  • 异步问题修复:等待所有CSV读取完成、所有API请求返回后再写入文件,避免异步导致的空值、[object Object]异常
  • 并发控制:可自行调整并发请求数,避免触发第三方API限流规则

内容的提问来源于stack exchange,提问作者apex2022

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:45:09