【问题标题】:JSON in CSV to CSVCSV 中的 JSON 到 CSV
【发布时间】:2018-01-13 09:18:35
【问题描述】:

通过 REST API 端点,我得到了具有以下结构的相当大的 CSV 文件(CSV 文件中的 JSON):

A,B,C,D
1,2,3,{"E":1,"F":2,"G":3}
1,2,3,{"E":1,"H":2}

对于不同的工具,我需要一个具有扁平结构(无嵌套 JSON)的 CSV。所以,最后,我想要一个看起来像这样的 CSV。

A,B,C,E,F,G,H
1,2,3,1,2,3,
1,2,3,1,,,2

(虽然列标题看起来很有条理,但这对我的用例并不重要)

由于 CSV 文件相当大,我正在寻找一种相对高效的方法来实现。我将用 JavaScript (Node.JS) 编写此代码(因为这是用于脚本所有其他部分的语言)。但是,现在我只是在寻找一种理论上的方法/假代码来解决性能问题。

据我所知,我可能需要循环两次 CSV 文件。第一次我只需要获取所有 JSON 密钥。第二次,我可以创建一个新的 CSV 文件并设置所有值。但是,我会正确找出我必须在哪一列中写入值吗?

或者在一个循环中将 CSV 文件“转换”为一组对象,然后使用类似 CSV 解析器 (http://csv.adaltas.com/) 之类的东西将其转换回 CSV 是否更高效?

【问题讨论】:

    标签: javascript json node.js csv


    【解决方案1】:

    这是使用jq的解决方案

    如果文件filter.jq 包含

    [
      split("\n")                                                  # split string into lines
    | (.[0]    | split(",")) as $headers                           # split header
    | (.[1:][] | split(","))                                       # split data rows
    | select(length>0)                                             # get rid of empty lines
    | $headers[:-1] as $h1                                         # fixed headers
    | .[:($h1|length)] as $p1                                      # fixed part
    | .[($h1|length):] as $p2                                      # variable part
    | (
         [   [ $h1, $p1 ]                                          # \  
           | transpose[]                                           #  \ assemble fixed object
           | {key:.[0], value:.[1]|tonumber}                       #  / from fixed keys and values
         ] | from_entries                                          # /
      ) + (
         $p2 | join(",") | fromjson                                # assemble variable object
      )
    ]
    
    | (map(keys) | add | unique) as $all                           # compute final headers
    | [$all] + (                                                   # add headers to
           map(. as $b | reduce $all[] as $a ([];. + [$b[$a]]))    # objects with all keys
         | map(map(if . == null then "" else tostring end))        # convert values to strings
      )
    | .[]                                                          # scan final array
    | @csv                                                         # convert to csv
    

    然后您的数据在一个名为 data 的文件中

    jq -M -R -s -r -f filter.jq data
    

    会生成

    "A","B","C","E","F","G","H"
    "1","2","3","1","2","3",""
    "1","2","3","1","","","2"
    

    【讨论】:

      【解决方案2】:
      var express = require('express');
      var app = express();
      var bodyParser = require('body-parser');
      var mysql=require('mysql');
      var fs= require('fs');
      var csv = require('fast-csv');
      var formidable = require('formidable');
      var urlencodedParser = bodyParser.urlencoded({ extended: false })
      var con=mysql.createConnection({
      host:'localhost',
      user:'dheeraj',
      password:'123',
      database:'dheeraj'
      });
      app.use('/assets',express.static('assets'));
      app.get('/d', function (req, res) {
         res.sendFile( __dirname + "/" + "/d.html" );
      })
      
      app.post('/file_upload', urlencodedParser, function (req, res) {
      
        //{
        var form = new formidable.IncomingForm();
        form.parse(req, function (err, fields, files) {
          res.write('File uploaded');
          //console.log(files.filetoupload);
      
          fs.createReadStream(files.filetoupload.name)
            .pipe(csv())
            .on('data',function(data){
              var d1=data[0];
                var d2=data[1];
                  var d3=data[2];
                    var d4=data[3];
                      var d5=data[4];
              con.query('insert into demo values(\''+d1+'\',\''+d2+'\',\''+d3+'\',\''+d4+'\',\''+d5+'\')',function(err,result)
                  {
                    console.log('inserted');
                  })
              console.log(data);
            })
            .on('end',function(data){
            console.log('read finished');
            });
      
          res.end();
      
      })
      })
      
      var server = app.listen(8081, function () {
      var host = server.address().address
      var port = server.address().port
      
      console.log("Example app listening at http://%s:%s", host, port)
      
      })
      

      【讨论】:

      • 这是我的代码,用于将 csv 文件上传到页面并检索可以插入到我的数据库中的数据。希望对你有帮助。
      • 谢谢,但这并不能解决我的问题,因为我的 CSV 数据中也包含 JSON 数据。
      猜你喜欢
      • 1970-01-01
      • 2021-12-27
      • 2018-07-30
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多