5

i have a data table in my angularjs app and i want to export it to a csv file .i searched alot in internet and i found this directive ,but this only work when button is next to table . need help to edit it...

app.directive('exportToCsv',function(){
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var el = element[0];
        element.bind('click', function(e){
            var table = e.target.nextElementSibling;//need to access to this element directly
            var csvString = '';
            for(var i=0; i<table.rows.length;i++){
                var rowData = table.rows[i].cells;
                for(var j=0; j<rowData.length;j++){
                    csvString = csvString + rowData[j].innerHTML + ",";
                }
                csvString = csvString.substring(0,csvString.length - 1);
                csvString = csvString + "\n";
            }
            csvString = csvString.substring(0, csvString.length - 1);
            var a = $('<a/>', {
                style:'display:none',
                href:'data:application/octet-stream;base64,'+btoa(csvString),
                download:'emailStatistics.csv'
            }).appendTo('body')
            a[0].click()
            a.remove();
        });
    }
}
});
2
  • was my answer helpful? Commented Dec 13, 2016 at 6:22
  • yeah ,i consider it as a secondary option but what i want to know is that how can i target table in my directive? Commented Dec 13, 2016 at 6:38

3 Answers 3

4

I would suggest you to use UI Grid which is available at this link here

The below code will allow you to export to either PDF or CSV

var app = angular.module('app', ['ngAnimate', 'ngTouch', 'ui.grid', 'ui.grid.selection', 'ui.grid.exporter', 'ui.grid.moveColumns']);

app.controller('MainCtrl', ['$scope', '$http', function ($scope, $http) {
  $scope.gridOptions = {
    columnDefs: [
      { field: 'name' },
      { field: 'gender', cellFilter: 'mapGender', exporterPdfAlign: 'right' },
      { field: 'company', visible: false }
    ],
    exporterLinkLabel: 'get your csv here',
    exporterPdfDefaultStyle: {fontSize: 9},
    exporterPdfTableStyle: {margin: [30, 30, 30, 30]},
    exporterPdfTableHeaderStyle: {fontSize: 10, bold: true, italics: true, color: 'red'},
    exporterPdfOrientation: 'portrait',
    exporterPdfPageSize: 'LETTER',
    exporterPdfMaxGridWidth: 500,
    exporterHeaderFilter: function( displayName ) { 
      if( displayName === 'Name' ) { 
        return 'Person Name'; 
      } else { 
        return displayName;
      } 
    },
    exporterFieldCallback: function( grid, row, col, input ) {
      if( col.name == 'gender' ){
        switch( input ){
          case 1:
            return 'female';
            break;
          case 2:
            return 'male';
            break;
          default:
            return 'unknown';
            break;
        }
      } else {
        return input;
      }
    },
    onRegisterApi: function(gridApi){ 
      $scope.gridApi = gridApi;
    }
  };

  $http.get('/data/100.json')
    .success(function(data) {
      data.forEach( function( row, index ) {
        if( row.gender === 'female' ){
          row.gender = 1;
        } else {
          row.gender = 2;
        }
      });
      $scope.gridOptions.data = data;
    });



  $scope.export = function(){
    if ($scope.export_format == 'csv') {
      var myElement = angular.element(document.querySelectorAll(".custom-csv-link-location"));
      $scope.gridApi.exporter.csvExport( $scope.export_row_type, $scope.export_column_type, myElement );
    } else if ($scope.export_format == 'pdf') {
      $scope.gridApi.exporter.pdfExport( $scope.export_row_type, $scope.export_column_type );
    };
  };
}])

.filter('mapGender', function() {
  return function( input ) {
    switch( input ){
      case 1:
        return 'female';
        break;
      case 2:
        return 'male';
        break;
      default:
        return 'unknown';
        break;
    }
  };
});

HTML will look like

  <div ui-grid="gridOptions" ui-grid-selection ui-grid-exporter ui-grid-move-columns class="grid"></div>
Sign up to request clarification or add additional context in comments.

Comments

4

u can do this

var app = angular.module('tableCSV',[]);
    app.directive('exportToCsv',function(){
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var el = element[0];
            element.bind('click', function(e){
                var table = e.target.previousElementSibling;
                var csvString = '';
                for(var i=0; i<table.rows.length;i++){
                    var rowData = table.rows[i].cells;
                    for(var j=0; j<rowData.length;j++){
                        csvString = csvString + rowData[j].innerHTML + ",";
                    }
                    csvString = csvString.substring(0,csvString.length - 1);
                    csvString = csvString + "\n";
                }
                csvString = csvString.substring(0, csvString.length - 1);
                var a = $('<a/>', {
                    style:'display:none',
                    href:'data:application/octet-stream;base64,'+btoa(csvString),
                    download:'emailStatistics.csv'
                }).appendTo('body')
                a[0].click()
                a.remove();
            });
        }
    }
    });

    app.controller('sampleController',function($scope){
        $scope.message = "";
    });

u must change nextElementSibling to previousElementSibling

Comments

3

getElementById() for dynamic element access

Directive

app.directive('exportToCsv',function(){
 return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var el = element[0];
            element.bind('click', function (e) {
                var idName = e.target.name;
                var fileName = idName.split("--")[0];
                var tableId = idName.split("--")[1];
                var table = document.getElementById(tableId);
                var csvString = '';
                for (var i = 0; i < table.rows.length; i++) {
                    var rowData = table.rows[i].cells;
                    for (var j = 0; j < rowData.length; j++) {
                        csvString = csvString + rowData[j].innerHTML + ",";
                    }
                    csvString = csvString.substring(0, csvString.length - 1);
                    csvString = csvString + "\n";
                }
                csvString = csvString.substring(0, csvString.length - 1);
                var a = $('<a/>', {
                    style: 'display:none',
                    href: 'data:application/octet-stream;base64,' + btoa(csvString),
                    download: fileName + '.csv'
                }).appendTo('body')
                a[0].click()
                a.remove();
            });
        }
    }
});

HTML

<button type="button" class="btn btn-primary" name="filename--divId" export-to-csv>Export posts</button>

Add a name element in the button tag where the first part is the file name & the second part is the id of the div to be selected.

Thank you.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.