在 Javascript 和 AngularJS 中解析 CSV

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24080602/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 02:09:44  来源:igfitidea点击:

parsing CSV in Javascript and AngularJS

javascriptangularjscsv

提问by user2656127

So I'm trying to create a basic angular application that parses some CSV input, and fills a table with the parsed data.

所以我试图创建一个基本的角度应用程序来解析一些 CSV 输入,并用解析的数据填充一个表。

You can see a plunker of what I'm trying to achieve here - http://plnkr.co/edit/6QFT4AcV4KpiSG23EdOS

你可以在这里看到我想要实现的目标 - http://plnkr.co/edit/6QFT4AcV4KpiSG23EdOS

Basically - as you can see - I have a <textarea>where the user will paste in some CSV, and the table below should then be filled with the data.

基本上 - 正如你所看到的 - 我有一个<textarea>用户将粘贴一些 CSV 的位置,然后应该用数据填充下表。

<div class="excelArea">
    <textarea name="excelData" ng-model="excelData"></textarea>
</div>

This is the javascript I have so far, but I'm struggling with a few things 1. Seperating the email from the name 2. Pushing the data back into the $scope.inviteList;

这是迄今为止我拥有的 javascript,但我正在努力解决一些问题 1. 将电子邮件与名称分开 2. 将数据推回 $scope.inviteList;

app.controller("InviteController", function($scope) {

    //Initliase objects
    $scope.excelData = "";
    $scope.errorMessage = "";
    $scope.inviteList = [];

    $scope.$watch("excelData", function() {

        var lines, lineNumber, data, length;

        lines = $scope.excelData.match(/[^\r\n]+/g);
        lineNumber = 0;

        for (var i = lines.length - 1; i >= 0; i--) {

            l = lines[i];
            lineNumber++;
            data = l.split(/\t/);

            var email = ? ? ?
            var name = ? ? ?

            $scope.inviteList.push({
                name: name,
                email: email,
                status: "not sent"
            });

        };

    });

});

Some basic information:

一些基本信息:

The CSV will be two columns (name, email) and will look like this:

CSV 将是两列(姓名、电子邮件),如下所示:

John Thompson,[email protected]
Robin Peters, [email protected]
Bill Bob, [email protected]

回答by Florian F.

Many problems in your code :

您的代码中有很多问题:

  • You could juste use split on your input instead of regexes, it makes everything easier
  • Your HTML isn't valid tdshould be inside trand not the other way around
  • Your array was never cleared
  • Your bindings inside ng-repeatdidn't use variable idefined here : i in inviteList
  • You should avoid unscoped variables (without varkeyword) whenever possible
  • 您可以对输入使用 split 而不是正则表达式,它使一切变得更容易
  • 你的 HTML 无效td应该在里面tr而不是相反
  • 您的阵列从未被清除
  • 您内部的绑定ng-repeat没有使用i此处定义的变量:i in inviteList
  • 你应该尽可能避免无作用域的变量(没有var关键字)

Otherwise, when you split a string, just access the splitted elements through their index.

否则,当您拆分字符串时,只需通过它们的索引访问拆分的元素。

Corrected code :

更正的代码:

JS

JS

$scope.$watch("excelData", function() {
    var lines, lineNumber, data, length;
    $scope.inviteList = [];
    lines = $scope.excelData.split('\n');
    lineNumber = 0;
    for (var i = lines.length - 1; i >= 0; i--) {
        l = lines[i];

        lineNumber++;
        data = l.split(',');

        var name = data[0];
        var email = data[1];

        $scope.inviteList.push({
            name: name,
            email: email,
            status: "not sent"
        });
    }
});

HTML

HTML

  <table>
    <tr>
      <th>Name</th>
      <th>Email</th>
      <th>Status</th>
    </tr>
    <tr ng-repeat="i in inviteList">
      <td>{{i.name}}</td>
      <td>{{i.email}}</td>
      <td>{{i.status}}</td>
    </tr>
  </table>

Your code (especially JS) can still be improved a lot and i encourage you to read docs/tutorials more.

您的代码(尤其是 JS)仍然可以改进很多,我鼓励您多阅读文档/教程。

And hereis the plunker to your working code.

这里是plunker你的工作代码。

回答by guru

I would create a filter to parse the data and reuse it anywhere I want it to. Logic:

我会创建一个过滤器来解析数据并在我想要的任何地方重用它。逻辑:

app.controller('MainCtrl', function($scope, $filter) {
  $scope.data = 'John Thompson,[email protected]\nRobin Peters, [email protected]\nBill Bob, [email protected]';

  $scope.$watch('data', function(val){
    $scope.inviteList = $filter('csvToObj')(val);
  });
});

app.filter('csvToObj', function() {
  return function(input) {
    var rows = input.split('\n');
    var obj = [];
    angular.forEach(rows, function(val) {
      var o = val.split(',');
      obj.push({
        name: o[0],
        email: o[1],
        status: "not sent"
      });
    });
    return obj;
  };
});

Sample Demo:http://plnkr.co/edit/SOtMMLft3amlVm4RROd0?p=preview

示例演示:http : //plnkr.co/edit/SOtMMLft3amlVm4RROd0?p=preview

回答by HaukurHaf

When you split a string, the return value is an array. I believe that you only have to access the correct indexes of the data array:

拆分字符串时,返回值是一个数组。我相信您只需要访问数据数组的正确索引:

app.controller("InviteController", function($scope) {

    //Initliase objects
    $scope.excelData = "";
    $scope.errorMessage = "";
    $scope.inviteList = [];

    $scope.$watch("excelData", function() {

        var lines, lineNumber, data, length;

        lines = $scope.excelData.match(/[^\r\n]+/g);
        lineNumber = 0;

        for (var i = lines.length - 1; i >= 0; i--) {

            l = lines[i];
            lineNumber++;
            data = l.split(/\t/);

            var email = data[1];
            var name = data[0];

            $scope.inviteList.push({
                name: name,
                email: email,
                status: "not sent"
            });

        };

    });

});