【问题标题】:Export JSON to CSV in Angular在 Angular 中将 JSON 导出为 CSV
【发布时间】:2015-08-12 15:22:55
【问题描述】:

我正在寻找使用 Angular 将 JSON 对象转换为 CSV 格式的方法。我遇到了这个https://www.npmjs.com/package/jsonexport,这正是我想要使用的那种东西,但我不确定我是否可以将它与 Angular 一起使用(似乎是特定于节点的?),如果没有,是否有任何现成的指令等在那里我可以输入一些 JSON 来获取 CSV。

谁能指点我一些有用的例子,我环顾四周,它们似乎很少,而且我发现的似乎只能处理非常基本的扁平 JSON 结构。

谢谢

【问题讨论】:

标签: json angularjs csv


【解决方案1】:

您可以使用这个简单的代码从 JSON 导出到 CSV。此代码解决了许多基本问题,例如分隔符问题、自定义标题、跳过空列和添加 - 代替特定列的空数据。请参阅此 github 链接以解决有关 Angular 中 CSV 导出的所有问题。

https://github.com/marvin-aroza/Angular-csv-export

将其视为 JSON 数据

jsonData : any = [{
    name : 'Berlin',
    age : '45',
    country : 'Spain',
    phone : '896514326'
  },
  {
    name : 'Professor',
    age : '42',
    country : 'spain'
  },
  {
    name : 'Tokyo',
    age : '35',
    phone : '854668244'
  },
  {
    name : 'Helsinki',
    phone : '35863297'
  }];

您可以使用这些功能下载 csv

exportCsv() {
    this.downloadFile(this.jsonData);
  }

  downloadFile(data, filename = 'data') {
    let arrHeader = ["name", "age", "country", "phone"];
    let csvData = this.ConvertToCSV(data, arrHeader);
    console.log(csvData)
    let blob = new Blob(['\ufeff' + csvData], { type: 'text/csv;charset=utf-8;' });
    let dwldLink = document.createElement("a");
    let url = URL.createObjectURL(blob);
    let isSafariBrowser = navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1;
    if (isSafariBrowser) {  //if Safari open in new window to save file with random filename.
      dwldLink.setAttribute("target", "_blank");
    }
    dwldLink.setAttribute("href", url);
    dwldLink.setAttribute("download", "sample.csv");
    dwldLink.style.visibility = "hidden";
    document.body.appendChild(dwldLink);
    dwldLink.click();
    document.body.removeChild(dwldLink);
  }

要编辑 CSV 的格式,您可以添加此功能

ConvertToCSV(objArray, headerList) {
    console.log(objArray);
    console.log(headerList);
    let array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
    let str = '';
    let row = 'S.No,';

    let newHeaders = ["Name", "Age", "Country", "Phone"];

    for (let index in newHeaders) {
      row += newHeaders[index] + ',';
    }
    row = row.slice(0, -1);
    str += row + '\r\n';
    for (let i = 0; i < array.length; i++) {
      let line = (i + 1) + '';
      for (let index in headerList) {
        let head = headerList[index];

        line += ',' + this.strRep(array[i][head]);
      }
      str += line + '\r\n';
    }
    return str;
  }

如果值带有逗号,您可以使用此功能删除逗号并将其视为一个单独的值

strRep(data) {
    if(typeof data == "string") {
      let newData = data.replace(/,/g, " ");
       return newData;
    }
    else if(typeof data == "undefined") {
      return "-";
    }
    else if(typeof data == "number") {
      return  data.toString();
    }
    else {
      return data;
    }
  }

【讨论】:

    【解决方案2】:

    试试这个http://ngmodules.org/modules/ng-csv

    对于工作示例 - https://asafdav.github.io/ng-csv/example/

    使用示例 js(取自他们的文档)

    脚本

        var myapp = angular.module('myapp', ["ngSanitize", "ngCsv"]);
    
        myapp.controller('myctrl', function ($scope) {
            $scope.filename = "test";
            $scope.getArray = [{a: 1, b:2}, {a:3, b:4}];
    
          $scope.addRandomRow = function() {
            $scope.getArray.push({a: Math.floor((Math.random()*10)+1), b: Math.floor((Math.random()*10)+1)});
          };
    
          $scope.getHeader = function () {return ["A", "B"]};
    
          $scope.clickFn = function() {
            console.log("click click click");
          };
        });
    

    标记

    <div ng-app="myapp">
        <div class="container" ng-controller="myctrl">
    
          <div class="page-header">
            <h1>ngCsv <small>example</small></h1>
          </div>
    
          <div class="form-group">
            <label for="filename">Filename </label>
            <input type="text" id="filename" class="form-control" ng-model="filename">
          </div>
    
          <div class="form-group">
            <label for="separator">Field separator</label>
            <input type="text" id="separator" class="form-control" ng-model="separator" ng-init="separator=','">
          </div>
    
          <div class="form-group">
            <label for="decimal-separator">Decimal separator</label>
            <input type="text" id="decimal-separator" class="form-control" ng-model="decimalSeparator" ng-init="decimalSeparator='.'">
          </div>            
    
          <button class="btn btn-default"
                  ng-csv="getArray" filename="{{ filename }}.csv" field-separator="{{separator}}" decimal-separator="{{decimalSeparator}}"
                  >Export to CSV</button>
    
          <button class="btn btn-default"
                  ng-csv="getArray" csv-header="getHeader()" filename="{{ filename }}" field-separator="{{separator}}" decimal-separator="{{decimalSeparator}}"
                  >Export to CSV with header</button>
    
          <button class="btn btn-default"
                  ng-csv="getArray" csv-header="getHeader()" filename="{{ filename }}" field-separator="{{separator}}" decimal-separator="{{decimalSeparator}}"
                  ng-click="clickFn()">Export with ng-click</button>
    
          <button class="btn btn-default"
                  ng-csv="getArray" filename="{{ filename }}.csv" field-separator="{{separator}}" decimal-separator="{{decimalSeparator}}" add-bom="true"
            >With BOM</button>
    
          <button class="btn btn-default" ng-click="addRandomRow()">Add row</button>
        </div>
    </div>
    

    【讨论】:

    • 谢谢亚历克斯,我确实遇到了这个(我应该在我的 OP 中这么说)并尝试了它,但在我的情况下,我有一个带有嵌套级别的复杂 JSON 结构,这个模块无法应对用它。我会继续四处看看!
    • ng-csv 是否能够处理出现在 json 中的对象?例如,您有一个订单,并且在该订单中有订单商品的位置。
    • @Alex:我可以使用嵌套对象的属性吗?或者只有它可以用简单的 json 来做
    【解决方案3】:

    ui-grid 中没有导出子网格数据的选项。但是我们还有另一种选择,可以使用 FileSaver.js 将 ui-grid 及其子网格数据导出为 .csv 文件。我创建了一个指令来获取网格数据/Json 数据,然后将数据格式化为树结构,然后使用 FileSaver.js 下载 .csv 文件。它有一个嵌套网格的限制。

        angular.module("exampleModule", [])
    .controller('exampleController', function ($scope) {
                    $scope.dataList = [
                        {
                            id: 1,
                            name: 'github',
                            price: '200$',
                            publisher: {
                                name: 'hieutran',
                                company: 'Dtag-VN'
                            },
                            nested:[
                             {
                                name: 'name1',
                                company: 'company1'
                            },
                            {
                                name: 'name2',
                                company: 'company2'
                            }]
                        },
                         {
                            id: 2,
                            name: 'twitter',
                            price: '500$',
                            publisher: {
                                name: 'twitter tran',
                                company: 'Canada'
                            },
                             nested:[]
                        },
    
                        {
                            id: 3,
                            name: 'google',
                            price: '300$',
                            publisher: {
                                name: 'tran',
                                company: 'Vietname'
                            },
                             nested:[
                             {
                                name: 'name3',
                                company: 'company3'
                            },
                            {
                                name: 'name4',
                                company: 'company4'
                            }]
                        }
                    ]
                })
                                .directive("ngGridJsonExportExcel", function($timeout) {
                                    return {
                                        restrict: "AE",
                                        scope: {
                                            data: "=",
                                            filename: "=?",
                                            reportFields: "=",
                                            nestedReportFields: "=",
                                            nestedDataProperty: "@"
                                        },
                                        link: function(scope, element) {
                                            scope.filename = !!scope.filename ? scope.filename : "export-excel";
    
                                            function generateFieldsAndHeaders(fieldsObject, fields, header) {
                                                _.forEach(fieldsObject, function(field, key) {
                                                    if (!field || !key) {
                                                        throw new Error("error json report fields");
                                                    }
                                                    fields.push(key);
                                                    header.push(field);
                                                });
                                                return {fields: fields, header: header};
                                            }
                                            var fieldsAndHeader = generateFieldsAndHeaders(scope.reportFields, [], []);
                                            var fields = fieldsAndHeader.fields, header = fieldsAndHeader.header;
                                            var nestedFieldsAndHeader = generateFieldsAndHeaders(scope.nestedReportFields, [], [""]);
                                            var nestedFields = nestedFieldsAndHeader.fields, nestedHeader = nestedFieldsAndHeader.header;
                                            function _convertToExcel(body, header) {
                                                return header + "\n" + body;
                                            }
                                            function _objectToString(object) {
                                                var output = "";
                                                _.forEach(object, function(value, key) {
                                                    output += key + ":" + value + " ";
                                                });
    
                                                return "'" + output + "'";
                                            }
                                            function generateFieldValues(list, rowItems, dataItem) {
                                                _.forEach(list, function(field) {
                                                    var data = "", fieldValue = "", curItem = null;
                                                    if (field.indexOf(".")) {
                                                        field = field.split(".");
                                                        curItem = dataItem;
                                                        // deep access to obect property
                                                        _.forEach(field, function(prop) {
                                                            if (curItem !== null && curItem !== undefined) {
                                                                curItem = curItem[prop];
                                                            }
                                                        });
                                                        data = curItem;
                                                    } else {
                                                        data = dataItem[field];
                                                    }
                                                    fieldValue = data !== null ? data : " ";
                                                    if (fieldValue !== undefined && angular.isObject(fieldValue)) {
                                                        fieldValue = _objectToString(fieldValue);
                                                    }
                                                    rowItems.push(fieldValue);
                                                });
                                                return rowItems;
                                            }
                                            function _bodyData() {
                                                var body = "";
    
                                                _.forEach(scope.data, function(dataItem) {
                                                    var rowItems = [];var nestedBody = "";
                                                    rowItems = generateFieldValues(fields, rowItems, dataItem);
                                                    //Nested Json body generation start 
                                                    if (scope.nestedDataProperty && dataItem[scope.nestedDataProperty].length) {
                                                        _.forEach(dataItem[scope.nestedDataProperty], function(nestedDataItem) {
                                                            var nestedRowItems = [""];
                                                            nestedRowItems = generateFieldValues(nestedFields, nestedRowItems, nestedDataItem);
                                                            nestedBody += nestedRowItems.toString() + "\n";
                                                        });
                                                        var strData = _convertToExcel(nestedBody, nestedHeader);
                                                        body += rowItems.toString() + "\n" + strData;
                                                        ////Nested Json body generation end 
                                                    } else {
                                                        body += rowItems.toString() + "\n";
                                                    }
                                                });
                                                return body;
                                            }
    
                                            $timeout(function() {
                                                element.bind("click", function() {
                                                    var bodyData = _bodyData();
                                                    var strData = _convertToExcel(bodyData, header);
                                                    var blob = new Blob([strData], {
                                                        type: "text/plain;charset=utf-8"
                                                    });
    
                                                    return saveAs(blob, [scope.filename + ".csv"]);
                                                });
                                            }, 1000);
                                        }
                                    };
                                });
    

    HTML 代码:

    <button ng-json-export-excel data="dataList"  nested-data-property="nested" report-fields="{id: 'ID Heder', name: 'Name Header', price: 'Price Head',  'publisher.name': 'Publisher Head', 'publisher.company': 'Company Head'}" nested-report-fields="{name: 'Nested Name', company: 'Nested Company'}">Json Export</button>
    

    Here is my plunker

    【讨论】:

    • 你如何在 jasmine 中测试这个?我一直在为这种类型的测试碰壁
    【解决方案4】:
     generateUserCSV() {
        this.emailService.getAllEmail().subscribe((res) => { this.downloadFile(res, 'emails') })
      }
    
    
      downloadFile(data, filename = 'data') {
        let csvData = this.ConvertToCSV(data, ['email', 'firstname', 'lastname']);
        console.log(csvData)
        let blob = new Blob(['\ufeff' + csvData], { type: 'text/csv;charset=utf-8;' });
        let dwldLink = document.createElement("a");
        let url = URL.createObjectURL(blob);
        let isSafariBrowser = navigator.userAgent.indexOf('Safari') != -1 && navigator.userAgent.indexOf('Chrome') == -1;
        if (isSafariBrowser) {  //if Safari open in new window to save file with random filename.
          dwldLink.setAttribute("target", "_blank");
        }
        dwldLink.setAttribute("href", url);
        dwldLink.setAttribute("download", filename + ".csv");
        dwldLink.style.visibility = "hidden";
        document.body.appendChild(dwldLink);
        dwldLink.click();
        document.body.removeChild(dwldLink);
      }
    
      ConvertToCSV(objArray, headerList) {
        let array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
        let str = '';
        let row = 'Index,';
    
        for (let index in headerList) {
          row += headerList[index] + ',';
        }
        row = row.slice(0, -1);
        str += row + '\r\n';
        for (let i = 0; i < array.length; i++) {
          let line = (i + 1) + '';
          for (let index in headerList) {
            let head = headerList[index];
    
            line += ',' + array[i][head];
          }
          str += line + '\r\n';
        }
        return str;
      }
    

    【讨论】:

    • 虽然此代码 sn-p 可能是解决方案,但 including an explanation 确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
    猜你喜欢
    • 1970-01-01
    • 2017-01-03
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 1970-01-01
    • 2020-09-23
    • 2019-07-24
    • 1970-01-01
    相关资源
    最近更新 更多