import {Component, Input, OnInit, Host} from '@angular/core';
+import {DomSanitizer, SafeUrl} from '@angular/platform-browser';
import {Pager} from '@eg/share/util/pager';
import {EgGridColumn, EgGridColumnSet, EgGridToolbarButton,
EgGridToolbarAction, EgGridContext, EgGridDataSource} from '@eg/share/grid/grid';
@Input() gridContext: EgGridContext;
@Input() colWidthConfig: EgGridColumnWidthComponent;
- constructor() {}
+ csvExportInProgress: boolean;
+ csvExportUrl: SafeUrl;
+ csvExportFileName: string;
+
+ constructor(private sanitizer: DomSanitizer) {}
ngOnInit() {}
action.action(this.gridContext.getSelectedRows());
}
- downloadCsv() {
- }
+ generateCsvExportUrl($event) {
+
+ if (this.csvExportInProgress) {
+ // This is secondary href click handler. Give the
+ // browser a moment to start the download, then reset
+ // the CSV download attributes / state.
+ setTimeout(() => {
+ this.csvExportUrl = null;
+ this.csvExportFileName = '';
+ this.csvExportInProgress = false;
+ }, 500
+ );
+ return;
+ }
+
+ this.csvExportInProgress = true;
+ // let the file name describe the grid
+ this.csvExportFileName = (
+ this.gridContext.mainLabel ||
+ this.gridContext.persistKey ||
+ 'eg_grid_data'
+ ).replace(/\s+/g, '_') + '.csv';
+
+ this.gridContext.gridToCsv().then(csv => {
+ console.log(csv);
+ var blob = new Blob([csv], {type : 'text/plain'});
+ let win: any = window;
+ this.csvExportUrl = this.sanitizer.bypassSecurityTrustUrl(
+ (win.URL || win.webkitURL).createObjectURL(blob)
+ );
+
+ // Fire the 2nd click event now that the browser has
+ // information on how to download the CSV file.
+ setTimeout(() => $event.target.click());
+ });
+
+ $event.preventDefault();
+ }
}
import {EgFormatService} from '@eg/share/util/format.service';
import {Pager} from '@eg/share/util/pager';
+const MAX_ALL_ROW_COUNT = 10000;
+
export class EgGridContext {
pager: Pager;
toolbarActions: EgGridToolbarAction[];
lastSelectedIndex: any;
pageChanges: Subscription;
+ mainLabel: string;
// Services injected by our grid component
idl: EgIdlService;
return this.format.transform({value: val, datatype: col.datatype});
}
+ getColumnTextContent(row: any, col: EgGridColumn): string {
+ if (col.cellTemplate) {
+ // TODO
+ } else {
+ return this.getRowColumnValue(row, col);
+ }
+ }
+
selectOneRow(index: any) {
this.rowSelector.clear();
this.rowSelector.select(index);
return this.dataSource.requestPage(this.pager);
}
+ getAllRows(): Promise<any> {
+ let pager = new Pager();
+ pager.offset = 0;
+ pager.limit = MAX_ALL_ROW_COUNT;
+ return this.dataSource.requestPage(pager);
+ }
+
+ // Returns a key/value pair object of visible column data as text.
+ getRowAsFlatText(row: any): any {
+ let flatRow = {};
+ this.columnSet.displayColumns().forEach(col => {
+ flatRow[col.name] =
+ this.getColumnTextContent(row, col);
+ });
+ return flatRow;
+ }
+
+ getAllRowsAsText(): Observable<any> {
+ return Observable.create(observer => {
+ this.getAllRows().then(ok => {
+ this.dataSource.data.forEach(row => {
+ observer.next(this.getRowAsFlatText(row));
+ })
+ observer.complete();
+ });
+ });
+ }
+
+ gridToCsv(): Promise<string> {
+
+ let csvStr = '';
+ let columns = this.columnSet.displayColumns();
+
+ // CSV header
+ columns.forEach(col => {
+ csvStr += this.valueToCsv(col.label),
+ csvStr += ',';
+ });
+
+ csvStr = csvStr.replace(/,$/,'\n');
+
+ return new Promise(resolve => {
+ this.getAllRowsAsText().subscribe(
+ row => {
+ columns.forEach(col => {
+ csvStr += this.valueToCsv(row[col.name]);
+ csvStr += ',';
+ });
+ csvStr = csvStr.replace(/,$/,'\n');
+ },
+ err => {},
+ () => resolve(csvStr)
+ );
+ });
+ }
+
+
+ // prepares a string for inclusion within a CSV document
+ // by escaping commas and quotes and removing newlines.
+ valueToCsv(str: string): string {
+ str = ''+str;
+ if (!str) return '';
+ str = str.replace(/\n/g, '');
+ if (str.match(/\,/) || str.match(/"/)) {
+ str = str.replace(/"/g, '""');
+ str = '"' + str + '"';
+ }
+ return str;
+ }
generateColumns() {
requestPage(pager: Pager): Promise<any> {
if (
- // already have the current page
- this.getPageOfRows(pager).length > 0
+ this.getPageOfRows(pager).length == pager.limit
// already have all data
|| this.allRowsRetrieved
// have no way to get more data.