Skip to content

Commit

Permalink
export documents in discover tab in CSV format
Browse files Browse the repository at this point in the history
  • Loading branch information
tongwang authored and fbaligand committed Apr 29, 2017
1 parent 6c330d3 commit c5dcc7b
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 1 deletion.
11 changes: 11 additions & 0 deletions src/ui/public/doc_table/doc_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@
class="doc-table-container"
ng-if="hits.length"
ng-class="{ loading: searchSource.activeFetchCount > 0 }">

<div class="export">
<small>Export:</small>&nbsp;&nbsp;
<a class="small" ng-click="exportAsCsv(false)">
Raw <i aria-hidden="true" class="fa fa-download"></i>
</a>&nbsp;&nbsp;&nbsp;
<a class="small" ng-click="exportAsCsv(true)">
Formatted <i aria-hidden="true" class="fa fa-download"></i>
</a>
</div>

<paginate ng-if="!infiniteScroll" list="hits" per-page="50" top-controls="true">
<table class="kbn-table table" ng-if="indexPattern">
<thead
Expand Down
71 changes: 70 additions & 1 deletion src/ui/public/doc_table/doc_table.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import _ from 'lodash';
import html from 'ui/doc_table/doc_table.html';
import getSort from 'ui/doc_table/lib/get_sort';
import { saveAs } from '@spalger/filesaver';
import 'ui/doc_table/doc_table.less';
import 'ui/directives/truncated';
import 'ui/directives/infinite_scroll';
import 'ui/doc_table/components/table_header';
import 'ui/doc_table/components/table_row';
import uiModules from 'ui/modules';
import RegistryFieldFormatsProvider from 'ui/registry/field_formats';



uiModules.get('kibana')
.directive('docTable', function (config, Notifier, getAppState) {
.directive('docTable', function (config, Notifier, getAppState, Private) {
let fieldFormats = Private(RegistryFieldFormatsProvider);
return {
restrict: 'E',
template: html,
Expand Down Expand Up @@ -109,6 +112,72 @@ uiModules.get('kibana')
$scope.searchSource.onError(notify.error).catch(notify.fatal);
}));

$scope.exportAsCsv = function (formatted) {
var csv = {
separator: config.get('csv:separator'),
quoteValues: config.get('csv:quoteValues')
};

var rows = $scope.hits;
var columns = $scope.columns;
var nonAlphaNumRE = /[^a-zA-Z0-9]/;
var allDoubleQuoteRE = /"/g;

function escape(val) {
if (_.isObject(val)) val = val.valueOf();
val = String(val);
if (csv.quoteValues && nonAlphaNumRE.test(val)) {
val = '"' + val.replace(allDoubleQuoteRE, '""') + '"';
}
return val;
}

function formatField(value, name) {
var field = $scope.indexPattern.fields.byName[name];
var defaultFormat = fieldFormats.getDefaultType(field.type);
var formatter = (field && field.format) ? field.format : defaultFormat;

return formatter.convert(value);
}

function formatRow(row) {
$scope.indexPattern.flattenHit(row);
row.$$_formatted = row.$$_formatted || _.mapValues(row.$$_flattened, formatField);
return row.$$_formatted;
}

// get column values for each row
var csvRows = rows.map(function (row, i) {
return columns.map(function (column, j) {
var val;

if (formatted) {
val = (row.$$_formatted || formatRow(row))[column];
} else {
val = (row.$$_flattened || formatRow(row))[column];
}

val = (val == null) ? '' : val;

return val;
});
});

// escape each cell in each row
csvRows = csvRows.map(function (row, i) {
return row.map(escape);
});

// add the columns to the rows
csvRows.unshift(columns.map(escape));

var data = csvRows.map(function (row) {
return row.join(csv.separator) + '\r\n';
}).join('');

saveAs(new Blob([data], { type: 'text/plain' }), 'export.csv');
};

}
};
});
4 changes: 4 additions & 0 deletions src/ui/public/doc_table/doc_table.less
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ doc-table {
z-index: 20;
opacity: @loading-opacity;
}

.export {
margin: 10px;
}
}

/**
Expand Down

0 comments on commit c5dcc7b

Please sign in to comment.