在nodejs中的CSV导出问题

我有excel表单和数据列表。

  1. 读取excel数据
  2. 使用API​​在另一个系统上searchexcel数据
  3. 以最高的结果数据和转换为CSV文件。

这一步运行良好。 但在此之后,我需要格式化CSV文件中的数据,如Excel数据和search结果都必须显示在CSV文件。

在这里,我不能把Excel数据导入CSV文件。例如“本田”是在Excel文件中的汽车名称,我正在读取它,并在另一个系统search。这些结果需要显示在CSV。

请指教。

Excelinput:

Car name, Description Honda, some description 

API响应数据:

 [{ "total": 10, "results": [{ "name": { "val": "Honda", "id": "0271b276", "type": "String", }, "attributes": [{ "val": "accord", "type": "field1", }, { "val": "test123", "type": "field3", }], }] }, ] 

期望输出在CSV文件中。

 Car Name , Description,Total results,Make , Model honda , Description,10 , Honda, accord 

 const _ = require('lodash'); const xlsx = require('xlsx'); const workbook = xlsx.readFile(__dirname + '/test.xlsx'); const worksheet = workbook.Sheets[workbook.SheetNames[0]]; for (let z in worksheet) { if(z.toString()[0] === 'A'){ request({ url: 'http://url', //URL to hit method: 'POST', json: { query: worksheet[z].v, } }, function(error, response, data){ if(error) { console.log(error); } else { var fields = ['Make','Model','total', 'results[0].name.val','results[0].name[0].val']; var fieldNames = ['Make','Model','Total','Name','Description']; var opts1 = { data: data, fields: fields, fieldNames: fieldNames, }; var json2csv = require('json2csv'); var csv = json2csv(opts1); fs.writeFile('file.csv', csv, function(err) { if (err) throw err; console.log('file saved'); }); 

我已经格式化了您的JSON,以便我可以更好地理解它:

 let data = [ { "total": 10, "results": [ { "name": { "val": "test value1", "id": "0271b276", "type": "String", }, "attributes": [ { "val": "test value2", "type": "field1", }, { "val": "test description", "type": "field2", }, { "val": "test123", "type": "field3", } ], } ] }, [ { "Make": "Honda", "Model": "Accord" } ] ]; 

这是一些奇怪的JSON。 在顶层,它是一个包含两个元素的数组。 第一个元素是一个对象,第二个元素是另一个数组。

你正在寻找的价值似乎是

  • data[1][0].Make (“Honda”)< – 注意大写的M
  • data[1][0].Model (“Accord”)< – 注意大写的M
  • data[0].total (10)
  • data[0].results[0].name.val (“test value1”)
  • data[0].results[0].attributes[0].val (“test value2”)

…但我不确定。

从json2csv的npm页面 ,数据对象必须是JSON对象的数组。 您必须将数据重构为json2csv能够理解的方式。 也许你的数据对象应该是这样的:

 [ { "name": { "val": "test name 1", "id": "0271b276", "type": "String" } "attributes": [ { "val": "attribute 1", "type": "String" }, { "val": "attribute 2", "type": "String" }, { "val": "attribute 3", "type": "String" } ], "make": "Honda", "model": "Accord" }, { "name": { "val": "test name 2", "id": "22e5b24e", "type": "String" } "attributes": [ { "val": "attribute A", "type": "String" }, { "val": "attribute B", "type": "String" }, { "val": "attribute C", "type": "String" } ], "make": "Toyota", "model": "Corolla" } ] 

正如之前所指出的,你的JSON看起来很奇怪。 如果对结构没有什么可以做的,我build议编写一个额外的图层来从嵌套的响应对象中提取数据。 这是它的configuration可能是这样的:

 var paths = [ { name: "Car Name", getter: function(resp) { return resp.results[0].name.val; } } ]; 

使用这个结构,你可以

  • 通过sortingpath数组,指定列的顺序
  • 指定如何使用getter函数获取数据
  • 指定如何使用name属性命名该列。

通过提供对path的响应来创build列:

 var row = { }; // keys: column names, values: row's values paths.forEach(function(path) { row[path.name] = path.getter(response); }); 

我试图在下面的代码片段中创build一个运行示例。 请注意,我必须:

  • 模拟json2csv库,我找不到一个CDN …
  • query提取“ Description字段而不是您的response (API响应数据没有描述)

当然,这个片段是在浏览器中运行的,可能需要额外的工作才能将它移植到nodejs。

重点是它显示了如何指定两种数据格式之间的转换逻辑

 var response = [{ "total": 10, "results": [{ "name": { "val": "Honda", "id": "0271b276", "type": "String", }, "attributes": [{ "val": "accord", "type": "field1", }, { "val": "test123", "type": "field3", }], }] }]; var paths = [{ name: "Car Name", source: "RESPONSE", getter: function(resp) { return resp.results[0].name.val; } }, { name: "Description", source: "QUERY", getter: function(query) { return query.Description; } }, { name: "Total results", source: "RESPONSE", getter: function(resp) { return resp.total; } }, { name: "Make", source: "RESPONSE", getter: function(resp) { return resp.results[0].name.val; } }, { name: "Model", source: "RESPONSE", getter: function(resp) { return resp.results[0].attributes[0].val; } }]; var processResponse = function(query, response) { var results = []; response.forEach(function(response) { var result = {}; paths.forEach(function(path) { var source; if (path.source === "RESPONSE") source = response; else if (path.source === "QUERY") source = query; else return; result[path.name] = path.getter(source); }); results.push(result); }); var csv = json2csv({ data: results, fields: paths.map(function(path) { return path.name; }) }); var pre = document.querySelector("pre"); document.querySelector("pre").innerHTML = csv; }; var testQuery = { "Car name": "Honda", "Description": "some description" }; processResponse(testQuery, response); // Mocking lib function json2csv(opts) { var head = opts.fields.join(","); var lines = opts.data .map(function(obj) { return opts.fields.map(function(k) { return obj[k]; }).join(","); }) return [head].concat(lines).join("\n"); }; 
 <h3>Output csv</h3> <pre style="background: #ccc"></pre>