Node.js+TS项目如何将外部API的JSON转换为CSV并按规则保存
功能实现修改方案
核心修复点
- 补充缺失的依赖导入:你代码中使用了
axios但未引入,同时新增path模块处理文件路径 - 新增输出目录
src/output自动创建逻辑,避免目录不存在时报错 - 修正未定义的
dir变量,指向项目根目录下的src/output - 调整单文件最大行数为999(含表头)
- 补充请求、转换、写文件全流程错误捕获,避免服务崩溃
- 增加接口响应返回,告知请求方导出结果
完整修改后代码
import { Request, Response } from 'express'; import axios from 'axios'; import * as path from 'path'; const converter = require("json-2-csv"); const fs = require("fs"); const flatten = require('flat'); const conf = require(`../config/${process.env.NODE_ENV}.json`); class IndexController { public async index(req: Request, res: Response) { try { const api = req.query.api as string; if (!conf.API_MOCS?.[api]?.url) { return res.status(400).send('无效的api参数'); } const url = conf.API_MOCS[api].url; const env = process.env.NODE_ENV; const nameFile = `${env}.${api}.csv`; // 拼接输出目录绝对路径,避免相对路径错误 const outputDir = path.resolve(__dirname, '../../src/output'); // 目录不存在则自动创建 if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); } // 请求接口数据 const { data } = await axios.get(url); const sourceData = data.items || []; // 自定义表头配置(你之前定义的header可以在这里传入生效) const csvOptions = { keys: Object.keys({ 'index':'Index', 'integer':'Integer', 'float': 'Float', 'name': 'Name' }), expandArrayObjects: true }; converter.json2csv(sourceData, (err: any, csv: any) => { if (err) throw err; const allLines = csv.split('\n'); const headerLine = allLines[0]; // 单文件最多999行,扣除表头后最多998条数据 const maxDataPerFile = 998; const dataLines = allLines.slice(1); const totalFile = Math.ceil(dataLines.length / maxDataPerFile); for (let i = 0; i < totalFile; i++) { const start = i * maxDataPerFile; const end = start + maxDataPerFile; const currentFileLines = [headerLine, ...dataLines.slice(start, end)]; const fileContent = currentFileLines.join('\n'); const filePath = path.join(outputDir, `${nameFile}.${i + 1}.csv`); fs.writeFileSync(filePath, fileContent); } return res.status(200).send(`CSV导出完成,共生成${totalFile}个文件`); }, csvOptions); } catch (e) { console.error('导出失败:', e); return res.status(500).send('CSV导出失败:' + (e as Error).message); } } } export const indexController = new IndexController();
注意事项
- 如果你不想用
axios,可以把请求部分替换为你已经引入的node-fetch实现 - 如果不需要自定义表头,删除
csvOptions配置项即可 - 路径计算是基于controller文件放在
src/controller目录下的常规结构,如果你的目录结构不同,调整path.resolve的参数即可
内容的提问来源于stack exchange,提问作者menphis
相关产品推荐
相关产品推荐

