///
import { Component, Input, OnChanges, SimpleChanges, AfterViewInit, QueryList, ContentChildren, OnDestroy, Output, EventEmitter, ElementRef, Inject, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'gc-column',
template: `
`
})
export class ColumnComponent implements OnChanges {
private changes: any = {};
private sheet: GC.Spread.Sheets.Worksheet;
private index: number;
//indicate all inputs
@Input() width: number;
@Input() dataField: string;
@Input() headerText: string;
@Input() visible: boolean;
@Input() resizable: boolean;
@Input() autoFit: boolean;
@Input() style: GC.Spread.Sheets.Style;
@Input() cellType: GC.Spread.Sheets.CellTypes.Base;
@Input() headerStyle: GC.Spread.Sheets.Style;
@Input() formatter: any;
public onAttached(sheet: GC.Spread.Sheets.Worksheet, index: number): void {
this.sheet = sheet;
this.index = index;
this.onColumnChanged();
}
private onColumnChanged() {
if (this.sheet) {
let sheet = this.sheet;
sheet.suspendPaint();
sheet.suspendEvent();
let changes = this.changes;
for (let changeName in changes) {
let newValue = changes[changeName].currentValue;
if (newValue === null || newValue === void 0) {
continue;
}
switch (changeName) {
case 'width':
sheet.setColumnWidth(this.index, newValue);
break;
case 'visible':
sheet.setColumnVisible(this.index, newValue);
break;
case 'resizable':
sheet.setColumnResizable(this.index, newValue);
break;
case 'autoFit':
if (newValue) {
sheet.autoFitColumn(this.index);
}
break;
case 'style':
sheet.setStyle(-1, this.index, newValue);
break;
case 'headerStyle':
sheet.setStyle(-1, this.index, newValue, GC.Spread.Sheets.SheetArea.colHeader);
break;
case 'cellType':
sheet.setCellType(-1, this.index, newValue);
break;
case 'formatter':
sheet.setFormatter(-1, this.index, newValue, GC.Spread.Sheets.SheetArea.viewport);
break;
}
}
sheet.resumeEvent();
sheet.resumePaint();
}
}
ngOnChanges(changes: SimpleChanges) {
this.changes = {};
let changesCache = this.changes;
for (let changeName in changes) {
changesCache[changeName] = changes[changeName];
}
this.onColumnChanged();
}
}
@Component({
selector: 'gc-worksheet',
template: `
`
})
export class WorksheetComponent implements OnChanges, AfterViewInit {
private sheet: GC.Spread.Sheets.Worksheet;
@ContentChildren(ColumnComponent)
columns: QueryList;
//indicate all inputs
@Input() rowCount: number;
@Input() colCount: number;
@Input() dataSource: any;
@Input() name: string;
@Input() frozenColumnCount: number;
@Input() frozenRowCount: number;
@Input() frozenTrailingRowCount: number;
@Input() frozenTrailingColumnCount: number;
@Input() allowCellOverflow: boolean;
@Input() frozenlineColor: string;
@Input() sheetTabColor: string;
@Input() selectionPolicy: number;
@Input() selectionUnit: number;
@Input() zoom: number;
@Input() currentTheme: string;
@Input() clipBoardOptions: number;
@Input() rowHeaderVisible: boolean;
@Input() colHeaderVisible: boolean;
@Input() rowHeaderAutoText: number;
@Input() colHeaderAutoText: number;
@Input() rowHeaderAutoTextIndex: number;
@Input() colHeaderAutoTextIndex: number;
@Input() isProtected: boolean;
@Input() showRowOutline: boolean;
@Input() showColumnOutline: boolean;
@Input() selectionBackColor: string;
@Input() selectionBorderColor: string;
@Input() defaultStyle: GC.Spread.Sheets.Style;
@Input() rowOutlineInfo: any[];
@Input() columnOutlineInfo: any[];
@Input() autoGenerateColumns: boolean;
constructor() {
this.sheet = new GC.Spread.Sheets.Worksheet("");
}
public onAttached(): void {
let sheet = this.sheet;
sheet.suspendPaint();
sheet.suspendEvent();
if (this.dataSource) {
sheet.setDataSource(this.dataSource);
this.columns.forEach((columnComponent: ColumnComponent, index: number) => {
if (columnComponent.dataField) {
sheet.bindColumn(index, {
name: columnComponent.dataField,
displayName: columnComponent.headerText
});
}
});
}
if (this.columns.length > 0) {
sheet.setColumnCount(this.columns.length);
this.columns.forEach((columnComponent: ColumnComponent, index: number) => {
columnComponent.onAttached(this.sheet, index);
});
}
sheet.resumeEvent();
sheet.resumePaint();
}
public getSheet() {
return this.sheet;
}
ngOnChanges(changes: SimpleChanges) {
let sheet = this.sheet;
sheet.suspendPaint();
sheet.suspendEvent();
for (let changeName in changes) {
let newValue = changes[changeName].currentValue;
if (newValue === null || newValue === void 0) {
continue;
}
switch (changeName) {
case "rowCount":
sheet.setRowCount(newValue);
break;
case "colCount":
sheet.setColumnCount(newValue);
break;
case "name":
sheet.name(newValue);
break;
case "frozenColumnCount":
sheet.frozenColumnCount(newValue);
break;
case "frozenRowCount":
sheet.frozenRowCount(newValue);
break;
case "frozenTrailingRowCount":
sheet.frozenTrailingRowCount(newValue);
break;
case "frozenTrailingColumnCount":
sheet.frozenTrailingColumnCount(newValue);
break;
case "selectionPolicy":
sheet.selectionPolicy(newValue);
break;
case "selectionUnit":
sheet.selectionUnit(newValue);
break;
case "zoom":
sheet.zoom(newValue);
break;
case "currentTheme":
sheet.currentTheme(newValue);
break;
case "defaultStyle":
sheet.setDefaultStyle(newValue);
break;
case "rowOutlineInfo":
newValue.forEach((item: any) => {
sheet.rowOutlines.group(item.index, item.count);
});
sheet.repaint();
break;
case "columnOutlineInfo":
newValue.forEach((item: any) => {
sheet.columnOutlines.group(item.index, item.count);
});
sheet.repaint();
break;
case "showRowOutline":
sheet.showRowOutline(newValue);
break;
case "showColumnOutline":
sheet.showColumnOutline(newValue);
break;
case "dataSource":
sheet.setDataSource(newValue);
break;
case "autoGenerateColumns":
sheet[changeName] = newValue;
default:
sheet.options[changeName] = newValue;
}
}
sheet.resumeEvent();
sheet.resumePaint();
}
ngAfterViewInit() {
this.columns.changes.subscribe(() => { this.onAttached() });
}
ngOnDestroy() {
let sheet = this.sheet;
let spread = sheet ? sheet.getParent() : null;
if (spread) {
let sheetIndex = spread.getSheetIndex(sheet.name());
if (sheetIndex !== void 0) {
spread.removeSheet(sheetIndex);
}
}
}
}
@Component({
selector: 'gc-spread-sheets',
template: `
`
})
export class SpreadSheetsComponent implements OnChanges, AfterViewInit, OnDestroy {
private elRef: ElementRef;
private spread: GC.Spread.Sheets.Workbook;
private spreadOptions: any[];
style = {
width: '800px',
height: '600px'
};
// indicate all options
@Input() allowUserResize: boolean;
@Input() allowUserZoom: boolean;
@Input() allowUserEditFormula: boolean;
@Input() allowUserDragFill: boolean;
@Input() allowUserDragDrop: boolean;
@Input() highlightInvalidData: boolean;
@Input() newTabVisible: boolean;
@Input() tabStripVisible: boolean;
@Input() tabEditable: boolean;
@Input() autoFitType: number;
@Input() referenceStyle: number;
@Input() backColor: string;
@Input() grayAreaBackColor: string;
@Input() showVerticalScrollbar: boolean;
@Input() showHorizontalScrollbar: boolean;
@Input() hostStyle: any; // used for get styles form parent host DIV
@Input() hostClass: string;
@Input() name: string;
@Input() backgroundImage: string;
@Input() backgroundImageLayout: number;
@Input() showScrollTip: number;
@Input() showResizeTip: number;
@Input() showDragDropTip: boolean;
@Input() showDragFillTip: boolean;
//outputs events
@Output() workbookInitialized = new EventEmitter();
@Output() validationError = new EventEmitter();
@Output() cellClick = new EventEmitter();
@Output() cellDoubleClick = new EventEmitter();
@Output() enterCell = new EventEmitter();
@Output() leaveCell = new EventEmitter();
@Output() valueChanged = new EventEmitter();
@Output() topRowChanged = new EventEmitter();
@Output() leftColumnChanged = new EventEmitter();
@Output() invalidOperation = new EventEmitter();
@Output() rangeFiltering = new EventEmitter();
@Output() rangeFiltered = new EventEmitter();
@Output() tableFiltering = new EventEmitter();
@Output() tableFiltered = new EventEmitter();
@Output() rangeSorting = new EventEmitter();
@Output() rangeSorted = new EventEmitter();
@Output() clipboardChanging = new EventEmitter();
@Output() clipboardChanged = new EventEmitter();
@Output() clipboardPasting = new EventEmitter();
@Output() clipboardPasted = new EventEmitter();
@Output() columnWidthChanging = new EventEmitter();
@Output() columnWidthChanged = new EventEmitter();
@Output() rowHeightChanging = new EventEmitter();
@Output() rowHeightChanged = new EventEmitter();
@Output() dragDropBlock = new EventEmitter();
@Output() dragDropBlockCompleted = new EventEmitter();
@Output() dragFillBlock = new EventEmitter();
@Output() dragFillBlockCompleted = new EventEmitter();
@Output() editStarting = new EventEmitter();
@Output() editChange = new EventEmitter();
@Output() editEnding = new EventEmitter();
@Output() editEnd = new EventEmitter();
@Output() editEnded = new EventEmitter();
@Output() rangeGroupStateChanging = new EventEmitter();
@Output() rangeGroupStateChanged = new EventEmitter();
@Output() selectionChanging = new EventEmitter();
@Output() selectionChanged = new EventEmitter();
@Output() sheetTabClick = new EventEmitter();
@Output() sheetTabDoubleClick = new EventEmitter();
@Output() sheetNameChanging = new EventEmitter();
@Output() sheetNameChanged = new EventEmitter();
@Output() userZooming = new EventEmitter();
@Output() userFormulaEntered = new EventEmitter();
@Output() cellChanged = new EventEmitter();
@Output() columnChanged = new EventEmitter();
@Output() rowChanged = new EventEmitter();
@Output() activeSheetChanging = new EventEmitter();
@Output() activeSheetChanged = new EventEmitter();
@Output() sparklineChanged = new EventEmitter();
@Output() rangeChanged = new EventEmitter();
@Output() buttonClicked = new EventEmitter();
@Output() editorStatusChanged = new EventEmitter();
@Output() floatingObjectChanged = new EventEmitter();
@Output() floatingObjectSelectionChanged = new EventEmitter();
@Output() pictureChanged = new EventEmitter();
@Output() floatingObjectRemoving = new EventEmitter();
@Output() floatingObjectRemoved = new EventEmitter();
@Output() pictureSelectionChanged = new EventEmitter();
@Output() floatingObjectLoaded = new EventEmitter();
@Output() touchToolStripOpening = new EventEmitter();
@Output() commentChanged = new EventEmitter();
@Output() commentRemoving = new EventEmitter();
@Output() commentRemoved = new EventEmitter();
@Output() slicerChanged = new EventEmitter();
@ContentChildren(WorksheetComponent)
sheets: QueryList;
constructor(@Inject(ElementRef) elRef: ElementRef) {
this.elRef = elRef;
}
ngAfterViewInit() {
let elRef = this.elRef;
let dom = elRef.nativeElement;
let hostElement = dom.querySelector('div');
this.spread = new GC.Spread.Sheets.Workbook(hostElement, { sheetCount: 0 });
this.setSpreadOptions();
this.initSheets();
this.sheets.changes.subscribe((changes) => { this.onSheetsChanged(changes) }) // may change sheets using bingidng.
this.bindCustomEvent(this.spread);
this.workbookInitialized.emit({ spread: this.spread });
}
private onSheetsChanged(sheetComponents: QueryList) {
let spread = this.spread;
spread.suspendPaint();
if (sheetComponents) {
sheetComponents.forEach((sheetComponent: WorksheetComponent, index: number) => {
let sheet = sheetComponent.getSheet();
if (sheet && !sheet.getParent()) {
spread.addSheet(index, sheetComponent.getSheet());
sheetComponent.onAttached();
}
});
}
spread.resumePaint();
}
private initSheets() {
let sheets = this.sheets;
let spread = this.spread;
spread.clearSheets();
sheets.forEach((sheetComponent, index) => {
spread.addSheet(index, sheetComponent.getSheet());
sheetComponent.onAttached();
});
// when there is no sheet, add default sheet to spread
if (sheets.length === 0) {
this.spread.addSheet(0, new GC.Spread.Sheets.Worksheet(""));
}
}
private bindCustomEvent(spread: GC.Spread.Sheets.Workbook) {
let customEventNameSpace = '.ng';
let events = ['ValidationError', 'CellClick', 'CellDoubleClick', 'EnterCell',
'LeaveCell', 'ValueChanged', 'TopRowChanged', 'LeftColumnChanged',
'InvalidOperation', 'RangeFiltering', 'RangeFiltered', 'TableFiltering',
'TableFiltered', 'RangeSorting', 'RangeSorted', 'ClipboardChanging',
'ClipboardChanged', 'ClipboardPasting', 'ClipboardPasted', 'ColumnWidthChanging',
'ColumnWidthChanged', 'RowHeightChanging', 'RowHeightChanged', 'DragDropBlock',
'DragDropBlockCompleted', 'DragFillBlock', 'DragFillBlockCompleted', 'EditStarting',
'EditChange', 'EditEnding', 'EditEnd', 'EditEnded', 'RangeGroupStateChanging',
'RangeGroupStateChanged', 'SelectionChanging', 'SelectionChanged', 'SheetTabClick',
'SheetTabDoubleClick', 'SheetNameChanging', 'SheetNameChanged',
'UserZooming', 'UserFormulaEntered', 'CellChanged', 'ColumnChanged',
'RowChanged', 'ActiveSheetChanging', 'ActiveSheetChanged',
'SparklineChanged',
'RangeChanged', 'ButtonClicked', 'EditorStatusChanged',
'FloatingObjectChanged', 'FloatingObjectSelectionChanged', 'PictureChanged', 'FloatingObjectRemoving', 'FloatingObjectRemoved', 'PictureSelectionChanged',
'FloatingObjectLoaded', 'TouchToolStripOpening', 'CommentChanged', 'CommentRemoving', 'CommentRemoved', 'SlicerChanged'];
events.forEach((event) => {
spread.bind(event + customEventNameSpace, (event: any, data: any) => {
let eventType = event.type;
let camelCaseEvent = eventType[0].toLowerCase() + eventType.substr(1);
this[camelCaseEvent].emit(data);
});
});
}
setSpreadOptions() {
let spread = this.spread;
if (!this.spread) {
return;
}
spread.suspendEvent();
spread.suspendPaint();
let options = this.spreadOptions;
options && options.forEach((option) => {
if (option.name === 'name') {
spread.name = option.value;
} else {
spread.options[option.name] = option.value;
}
});
spread.resumePaint();
spread.resumeEvent();
}
ngOnChanges(changes: SimpleChanges) {
let options = [];
for (let changeName in changes) {
let newValue = changes[changeName].currentValue;
if (newValue !== null && newValue !== void 0) {
switch (changeName) {
case 'hostStyle':
this.style = newValue;
break;
case 'hostClass':
break;
default:
options.push({ name: changeName, value: newValue });
}
}
}
this.spreadOptions = options;
this.setSpreadOptions();
}
ngOnDestroy() {
this.spread.destroy();
}
}
@NgModule({
imports: [CommonModule],
declarations: [SpreadSheetsComponent, WorksheetComponent, ColumnComponent],
exports: [SpreadSheetsComponent, WorksheetComponent, ColumnComponent]
})
export class SpreadSheetsModule {
}