<!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>  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);
}
};
}]);