<!DOCTYPE html>
<html>

<head>
  <link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
  <script data-require="angular.js@1.3.15" data-semver="1.3.15" src="https://code.angularjs.org/1.3.15/angular.js"></script>
  <script data-require="ui-bootstrap@*" data-semver="0.13.0" src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.13.0.min.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
  <script src="ng-table-export.src.js"></script>
</head>

<body ng-app="ng-table-to-csv-demo">
  <div data-ng-controller="DemoCtrl">
    <h1>{{title}}</h1>
    <a ng-controller="DemoCtrl" class="btn" title="Export Table" ng-click='csv.generate($event, "my-file.csv")' href=''>Export</a>
    <table class="table table-bordered" export-csv="csv" 
    separator=";" export-csv-ignore="ignore">
      <tr>
        <th>Entry Header 1</th>
        <th>Entry Header 2</th>
        <th>Entry Header 3</th>
        <th>Entry Header 4</th>
      </tr>
      <tr>
        <td>Entry First Line 1</td>
        <td>Entry First Line 2</td>
        <td>Entry First Line 3</td>
        <td>Entry First Line 4</td>
      </tr>
      <tr>
        <td>Entry Line 1</td>
        <td>Entry Line 2</td>
        <td>Entry Line 3</td>
        <td>Entry Line 4</td>
      </tr>
      <tr>
        <td>Entry Last Line 1</td>
        <td>Entry Last Line 2</td>
        <td>Entry Last Line 3</td>
        <td>Entry Last Line 4</td>
      </tr>
      <tr class="ignore">
        <td>Don't export me 1</td>
        <td>Don't export me 2</td>
        <td>Don't export me 3</td>
        <td>Don't export me 4</td>
      </tr>
    </table>
  </div>
</body>

</html>
// Code goes here

angular.module('ng-table-to-csv-demo', ['ngTableExport'])
.controller('DemoCtrl',['$scope',function($scope){
  $scope.title = "ng-table-to-csv";
}]);
/* Styles go here */

# [ng-table-to-csv](https://github.com/kollavarsham/ng-table-to-csv)

## Angular.js Module for exporting Tables to CSV

As opposed to [the forked library](https://github.com/esvit/ng-table-export), this version does not have a dependency on `ng-table` and can export any HTML table.

## Installation

With Bower:

```shell
bower install ng-table-to-csv --save
```

## Usage

Add `export-csv` attribute directive on the table to define a new `csv` object in the scope with `generate()` and `link()` functions on them. See below: 

```html
      <a class="btn" title="Export Table" ng-click='csv.generate()' ng-href="{{ csv.link() }}"
         download="myTable.csv">
        <i class="glyphicon glyphicon-new-window"></i> &#160;Export
      </a>
      <table class="table table-bordered" export-csv="csv">
        <!-- table contents -->
      </table>
```

#### License

MIT License - Copyright (c) 2015 The Kollavarsham Team

#### Original License

Code originally released under [New BSD License](https://github.com/esvit/ng-table-export/blob/master/LICENSE) by [@esvit](https://github.com/esvit) at [esvit](https://github.com/esvit)/[ng-table-export](https://github.com/esvit/ng-table-export).
angular.module('ngTableExport', [])
.config(['$compileProvider', function($compileProvider) {
    // allow data links
    $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|data):/);
}])
.directive('exportCsv', ['$parse', '$timeout', 'ngTableEventsChannel', function ($parse, $timeout, ngTableEventsChannel) {

  var delimiter = ',';
  var header = 'data:text/csv;charset=UTF-8,';

  return {
      restrict: 'A',
      scope: false,

      /**
       * scope is table scope, element is <table>
       */
      link: function(scope, element, attrs) {

          var data = '';

          // allow pass in of delimiter via directive attrs
          if (attrs.delimiter) { delimiter = attrs.delimiter; }

          function stringify(str) {
            return '"' +
              str.replace(/^\s\s*/, '').replace(/\s*\s$/, '') // trim spaces
                 .replace(/"/g,'""') + // replace quotes with double quotes
              '"';
          }

          /**
           * Parse the table and build up data uri
           */
          function parseTable() {
            data = '';
            var rows = element.find('tr');
            angular.forEach(rows, function(row, i) {
              var tr = angular.element(row),
                tds = tr.find('th'),
                rowData = '';
              if (tr.hasClass('ng-table-filters')) {
                return;
              }
              if (tds.length === 0) {
                tds = tr.find('td');
              }
              if (i !== 1) {
                angular.forEach(tds, function(td) {
                  // respect colspan in row data
                  rowData += stringify(angular.element(td).text()) + Array.apply(null, Array(td.colSpan)).map(function () { return delimiter; }).join('');
                });
                rowData = rowData.slice(0, rowData.length - 1); //remove last semicolon
              }
              data += rowData + '\n';
            });
            // add delimiter hint for excel so it opens without having to import
            data = 'sep=' + delimiter + '\n' + data;
          }

          /**
           * Dynamically generate a link and click it; works in chrome + firefox; unfortunately, safari
           * does not support the `download` attribute, so it ends up opening the file in a new tab https://bugs.webkit.org/show_bug.cgi?id=102914
           */
          function download(dataUri, filename, scope) {
            // tested in chrome / firefox / safari
            var link = document.createElement('a');
            // chrome + firefox
            link.style.display = 'none';
            link.href = dataUri;
            link.download = filename;
            link.target = '_blank';
            // needs to get wrapped to play nicely with angular $digest
            // else may cause '$digest already in progress' errors with other angular controls (e.g. angular-ui dropdown)
            $timeout(function () {
              try {
                // must append to body for firefox; chrome & safari don't mind
                document.body.appendChild(link);
                link.click();
                // destroy
                document.body.removeChild(link);
              }
              catch(err) {
                if (scope.logError) {
                  scope.logError('NG Table Export Error saving file on client.');
                }
                throw(err);
              }
            }, 0, false);
          }

          var csv = {
            /**
             *  Generate data URI from table data
             */
            generate: function(event, filename, table) {

              var isNgTable = attrs.ngTable,
                table = table || scope.$parent.tableParams,
                settings = table ? table.settings() : {},
                cnt = table ? table.count() : {},
                total = table ? settings.total : {};

              // is pager on?  if so, we have to disable it temporarily
              if (isNgTable && cnt < total) {
                var $off = ngTableEventsChannel.onAfterReloadData(function () {
                  // de-register callback so it won't continue firing
                  $off();
                  // give browser some time to re-render; FIXME - no good way to know when rendering is done?
                  $timeout(function () {
                    // generate data from table
                    parseTable();
                    // finally, restore original table cnt
                    table.count(cnt);
                    table.reload();
                    // dynamically trigger download
                    download(header + encodeURIComponent(data), filename, scope);
                  }, 1000, false);
                });

                // disable the pager and reload the table so we get all the data
                table.count(Infinity);
                table.reload();

              } else {
                // pager isn't on, just parse the table
                parseTable();
                download(header + encodeURIComponent(data), filename);
              }
            }
          };

          // attach csv to table scope
          $parse(attrs.exportCsv).assign(scope.$parent, csv);
      }
  };
}]);