gc.spread.sheets.angular.11.2.2.ts 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. ///<reference path="./GC.Spread.Sheets.d.ts" />
  2. import { Component, Input, OnChanges, SimpleChanges, AfterViewInit, QueryList, ContentChildren, OnDestroy, Output, EventEmitter, ElementRef, Inject, NgModule } from '@angular/core';
  3. import { CommonModule } from '@angular/common';
  4. @Component({
  5. selector: 'gc-column',
  6. template: `
  7. <ng-content></ng-content>
  8. `
  9. })
  10. export class ColumnComponent implements OnChanges {
  11. private changes: any = {};
  12. private sheet: GC.Spread.Sheets.Worksheet;
  13. private index: number;
  14. //indicate all inputs
  15. @Input() width: number;
  16. @Input() dataField: string;
  17. @Input() headerText: string;
  18. @Input() visible: boolean;
  19. @Input() resizable: boolean;
  20. @Input() autoFit: boolean;
  21. @Input() style: GC.Spread.Sheets.Style;
  22. @Input() cellType: GC.Spread.Sheets.CellTypes.Base;
  23. @Input() headerStyle: GC.Spread.Sheets.Style;
  24. @Input() formatter: any;
  25. public onAttached(sheet: GC.Spread.Sheets.Worksheet, index: number): void {
  26. this.sheet = sheet;
  27. this.index = index;
  28. this.onColumnChanged();
  29. }
  30. private onColumnChanged() {
  31. if (this.sheet) {
  32. let sheet = this.sheet;
  33. sheet.suspendPaint();
  34. sheet.suspendEvent();
  35. let changes = this.changes;
  36. for (let changeName in changes) {
  37. let newValue = changes[changeName].currentValue;
  38. if (newValue === null || newValue === void 0) {
  39. continue;
  40. }
  41. switch (changeName) {
  42. case 'width':
  43. sheet.setColumnWidth(this.index, newValue);
  44. break;
  45. case 'visible':
  46. sheet.setColumnVisible(this.index, newValue);
  47. break;
  48. case 'resizable':
  49. sheet.setColumnResizable(this.index, newValue);
  50. break;
  51. case 'autoFit':
  52. if (newValue) {
  53. sheet.autoFitColumn(this.index);
  54. }
  55. break;
  56. case 'style':
  57. sheet.setStyle(-1, this.index, newValue);
  58. break;
  59. case 'headerStyle':
  60. sheet.setStyle(-1, this.index, newValue, GC.Spread.Sheets.SheetArea.colHeader);
  61. break;
  62. case 'cellType':
  63. sheet.setCellType(-1, this.index, newValue);
  64. break;
  65. case 'formatter':
  66. sheet.setFormatter(-1, this.index, newValue, GC.Spread.Sheets.SheetArea.viewport);
  67. break;
  68. }
  69. }
  70. sheet.resumeEvent();
  71. sheet.resumePaint();
  72. }
  73. }
  74. ngOnChanges(changes: SimpleChanges) {
  75. this.changes = {};
  76. let changesCache = this.changes;
  77. for (let changeName in changes) {
  78. changesCache[changeName] = changes[changeName];
  79. }
  80. this.onColumnChanged();
  81. }
  82. }
  83. @Component({
  84. selector: 'gc-worksheet',
  85. template: `
  86. <ng-content></ng-content>
  87. `
  88. })
  89. export class WorksheetComponent implements OnChanges, AfterViewInit {
  90. private sheet: GC.Spread.Sheets.Worksheet;
  91. @ContentChildren(ColumnComponent)
  92. columns: QueryList<ColumnComponent>;
  93. //indicate all inputs
  94. @Input() rowCount: number;
  95. @Input() colCount: number;
  96. @Input() dataSource: any;
  97. @Input() name: string;
  98. @Input() frozenColumnCount: number;
  99. @Input() frozenRowCount: number;
  100. @Input() frozenTrailingRowCount: number;
  101. @Input() frozenTrailingColumnCount: number;
  102. @Input() allowCellOverflow: boolean;
  103. @Input() frozenlineColor: string;
  104. @Input() sheetTabColor: string;
  105. @Input() selectionPolicy: number;
  106. @Input() selectionUnit: number;
  107. @Input() zoom: number;
  108. @Input() currentTheme: string;
  109. @Input() clipBoardOptions: number;
  110. @Input() rowHeaderVisible: boolean;
  111. @Input() colHeaderVisible: boolean;
  112. @Input() rowHeaderAutoText: number;
  113. @Input() colHeaderAutoText: number;
  114. @Input() rowHeaderAutoTextIndex: number;
  115. @Input() colHeaderAutoTextIndex: number;
  116. @Input() isProtected: boolean;
  117. @Input() showRowOutline: boolean;
  118. @Input() showColumnOutline: boolean;
  119. @Input() selectionBackColor: string;
  120. @Input() selectionBorderColor: string;
  121. @Input() defaultStyle: GC.Spread.Sheets.Style;
  122. @Input() rowOutlineInfo: any[];
  123. @Input() columnOutlineInfo: any[];
  124. @Input() autoGenerateColumns: boolean;
  125. constructor() {
  126. this.sheet = new GC.Spread.Sheets.Worksheet("");
  127. }
  128. public onAttached(): void {
  129. let sheet = this.sheet;
  130. sheet.suspendPaint();
  131. sheet.suspendEvent();
  132. if (this.dataSource) {
  133. sheet.setDataSource(this.dataSource);
  134. this.columns.forEach((columnComponent: ColumnComponent, index: number) => {
  135. if (columnComponent.dataField) {
  136. sheet.bindColumn(index, {
  137. name: columnComponent.dataField,
  138. displayName: columnComponent.headerText
  139. });
  140. }
  141. });
  142. }
  143. if (this.columns.length > 0) {
  144. sheet.setColumnCount(this.columns.length);
  145. this.columns.forEach((columnComponent: ColumnComponent, index: number) => {
  146. columnComponent.onAttached(this.sheet, index);
  147. });
  148. }
  149. sheet.resumeEvent();
  150. sheet.resumePaint();
  151. }
  152. public getSheet() {
  153. return this.sheet;
  154. }
  155. ngOnChanges(changes: SimpleChanges) {
  156. let sheet = this.sheet;
  157. sheet.suspendPaint();
  158. sheet.suspendEvent();
  159. for (let changeName in changes) {
  160. let newValue = changes[changeName].currentValue;
  161. if (newValue === null || newValue === void 0) {
  162. continue;
  163. }
  164. switch (changeName) {
  165. case "rowCount":
  166. sheet.setRowCount(newValue);
  167. break;
  168. case "colCount":
  169. sheet.setColumnCount(newValue);
  170. break;
  171. case "name":
  172. sheet.name(newValue);
  173. break;
  174. case "frozenColumnCount":
  175. sheet.frozenColumnCount(newValue);
  176. break;
  177. case "frozenRowCount":
  178. sheet.frozenRowCount(newValue);
  179. break;
  180. case "frozenTrailingRowCount":
  181. sheet.frozenTrailingRowCount(newValue);
  182. break;
  183. case "frozenTrailingColumnCount":
  184. sheet.frozenTrailingColumnCount(newValue);
  185. break;
  186. case "selectionPolicy":
  187. sheet.selectionPolicy(newValue);
  188. break;
  189. case "selectionUnit":
  190. sheet.selectionUnit(newValue);
  191. break;
  192. case "zoom":
  193. sheet.zoom(newValue);
  194. break;
  195. case "currentTheme":
  196. sheet.currentTheme(newValue);
  197. break;
  198. case "defaultStyle":
  199. sheet.setDefaultStyle(newValue);
  200. break;
  201. case "rowOutlineInfo":
  202. newValue.forEach((item: any) => {
  203. sheet.rowOutlines.group(item.index, item.count);
  204. });
  205. sheet.repaint();
  206. break;
  207. case "columnOutlineInfo":
  208. newValue.forEach((item: any) => {
  209. sheet.columnOutlines.group(item.index, item.count);
  210. });
  211. sheet.repaint();
  212. break;
  213. case "showRowOutline":
  214. sheet.showRowOutline(newValue);
  215. break;
  216. case "showColumnOutline":
  217. sheet.showColumnOutline(newValue);
  218. break;
  219. case "dataSource":
  220. sheet.setDataSource(newValue);
  221. break;
  222. case "autoGenerateColumns":
  223. sheet[changeName] = newValue;
  224. default:
  225. sheet.options[changeName] = newValue;
  226. }
  227. }
  228. sheet.resumeEvent();
  229. sheet.resumePaint();
  230. }
  231. ngAfterViewInit() {
  232. this.columns.changes.subscribe(() => { this.onAttached() });
  233. }
  234. ngOnDestroy() {
  235. let sheet = this.sheet;
  236. let spread = sheet ? sheet.getParent() : null;
  237. if (spread) {
  238. let sheetIndex = spread.getSheetIndex(sheet.name());
  239. if (sheetIndex !== void 0) {
  240. spread.removeSheet(sheetIndex);
  241. }
  242. }
  243. }
  244. }
  245. @Component({
  246. selector: 'gc-spread-sheets',
  247. template: `
  248. <div [ngStyle]="style" [ngClass]="hostClass">
  249. <ng-content></ng-content>
  250. </div>
  251. `
  252. })
  253. export class SpreadSheetsComponent implements OnChanges, AfterViewInit, OnDestroy {
  254. private elRef: ElementRef;
  255. private spread: GC.Spread.Sheets.Workbook;
  256. private spreadOptions: any[];
  257. style = {
  258. width: '800px',
  259. height: '600px'
  260. };
  261. // indicate all options
  262. @Input() allowUserResize: boolean;
  263. @Input() allowUserZoom: boolean;
  264. @Input() allowUserEditFormula: boolean;
  265. @Input() allowUserDragFill: boolean;
  266. @Input() allowUserDragDrop: boolean;
  267. @Input() highlightInvalidData: boolean;
  268. @Input() newTabVisible: boolean;
  269. @Input() tabStripVisible: boolean;
  270. @Input() tabEditable: boolean;
  271. @Input() autoFitType: number;
  272. @Input() referenceStyle: number;
  273. @Input() backColor: string;
  274. @Input() grayAreaBackColor: string;
  275. @Input() showVerticalScrollbar: boolean;
  276. @Input() showHorizontalScrollbar: boolean;
  277. @Input() hostStyle: any; // used for get styles form parent host DIV
  278. @Input() hostClass: string;
  279. @Input() name: string;
  280. @Input() backgroundImage: string;
  281. @Input() backgroundImageLayout: number;
  282. @Input() showScrollTip: number;
  283. @Input() showResizeTip: number;
  284. @Input() showDragDropTip: boolean;
  285. @Input() showDragFillTip: boolean;
  286. //outputs events
  287. @Output() workbookInitialized = new EventEmitter<any>();
  288. @Output() validationError = new EventEmitter<any>();
  289. @Output() cellClick = new EventEmitter<any>();
  290. @Output() cellDoubleClick = new EventEmitter<any>();
  291. @Output() enterCell = new EventEmitter<any>();
  292. @Output() leaveCell = new EventEmitter<any>();
  293. @Output() valueChanged = new EventEmitter<any>();
  294. @Output() topRowChanged = new EventEmitter<any>();
  295. @Output() leftColumnChanged = new EventEmitter<any>();
  296. @Output() invalidOperation = new EventEmitter<any>();
  297. @Output() rangeFiltering = new EventEmitter<any>();
  298. @Output() rangeFiltered = new EventEmitter<any>();
  299. @Output() tableFiltering = new EventEmitter<any>();
  300. @Output() tableFiltered = new EventEmitter<any>();
  301. @Output() rangeSorting = new EventEmitter<any>();
  302. @Output() rangeSorted = new EventEmitter<any>();
  303. @Output() clipboardChanging = new EventEmitter<any>();
  304. @Output() clipboardChanged = new EventEmitter<any>();
  305. @Output() clipboardPasting = new EventEmitter<any>();
  306. @Output() clipboardPasted = new EventEmitter<any>();
  307. @Output() columnWidthChanging = new EventEmitter<any>();
  308. @Output() columnWidthChanged = new EventEmitter<any>();
  309. @Output() rowHeightChanging = new EventEmitter<any>();
  310. @Output() rowHeightChanged = new EventEmitter<any>();
  311. @Output() dragDropBlock = new EventEmitter<any>();
  312. @Output() dragDropBlockCompleted = new EventEmitter<any>();
  313. @Output() dragFillBlock = new EventEmitter<any>();
  314. @Output() dragFillBlockCompleted = new EventEmitter<any>();
  315. @Output() editStarting = new EventEmitter<any>();
  316. @Output() editChange = new EventEmitter<any>();
  317. @Output() editEnding = new EventEmitter<any>();
  318. @Output() editEnd = new EventEmitter<any>();
  319. @Output() editEnded = new EventEmitter<any>();
  320. @Output() rangeGroupStateChanging = new EventEmitter<any>();
  321. @Output() rangeGroupStateChanged = new EventEmitter<any>();
  322. @Output() selectionChanging = new EventEmitter<any>();
  323. @Output() selectionChanged = new EventEmitter<any>();
  324. @Output() sheetTabClick = new EventEmitter<any>();
  325. @Output() sheetTabDoubleClick = new EventEmitter<any>();
  326. @Output() sheetNameChanging = new EventEmitter<any>();
  327. @Output() sheetNameChanged = new EventEmitter<any>();
  328. @Output() userZooming = new EventEmitter<any>();
  329. @Output() userFormulaEntered = new EventEmitter<any>();
  330. @Output() cellChanged = new EventEmitter<any>();
  331. @Output() columnChanged = new EventEmitter<any>();
  332. @Output() rowChanged = new EventEmitter<any>();
  333. @Output() activeSheetChanging = new EventEmitter<any>();
  334. @Output() activeSheetChanged = new EventEmitter<any>();
  335. @Output() sparklineChanged = new EventEmitter<any>();
  336. @Output() rangeChanged = new EventEmitter<any>();
  337. @Output() buttonClicked = new EventEmitter<any>();
  338. @Output() editorStatusChanged = new EventEmitter<any>();
  339. @Output() floatingObjectChanged = new EventEmitter<any>();
  340. @Output() floatingObjectSelectionChanged = new EventEmitter<any>();
  341. @Output() pictureChanged = new EventEmitter<any>();
  342. @Output() floatingObjectRemoving = new EventEmitter<any>();
  343. @Output() floatingObjectRemoved = new EventEmitter<any>();
  344. @Output() pictureSelectionChanged = new EventEmitter<any>();
  345. @Output() floatingObjectLoaded = new EventEmitter<any>();
  346. @Output() touchToolStripOpening = new EventEmitter<any>();
  347. @Output() commentChanged = new EventEmitter<any>();
  348. @Output() commentRemoving = new EventEmitter<any>();
  349. @Output() commentRemoved = new EventEmitter<any>();
  350. @Output() slicerChanged = new EventEmitter<any>();
  351. @ContentChildren(WorksheetComponent)
  352. sheets: QueryList<WorksheetComponent>;
  353. constructor(@Inject(ElementRef) elRef: ElementRef) {
  354. this.elRef = elRef;
  355. }
  356. ngAfterViewInit() {
  357. let elRef = this.elRef;
  358. let dom = <HTMLElement>elRef.nativeElement;
  359. let hostElement = dom.querySelector('div');
  360. this.spread = new GC.Spread.Sheets.Workbook(hostElement, { sheetCount: 0 });
  361. this.setSpreadOptions();
  362. this.initSheets();
  363. this.sheets.changes.subscribe((changes) => { this.onSheetsChanged(changes) }) // may change sheets using bingidng.
  364. this.bindCustomEvent(this.spread);
  365. this.workbookInitialized.emit({ spread: this.spread });
  366. }
  367. private onSheetsChanged(sheetComponents: QueryList<WorksheetComponent>) {
  368. let spread = this.spread;
  369. spread.suspendPaint();
  370. if (sheetComponents) {
  371. sheetComponents.forEach((sheetComponent: WorksheetComponent, index: number) => {
  372. let sheet = sheetComponent.getSheet();
  373. if (sheet && !sheet.getParent()) {
  374. spread.addSheet(index, sheetComponent.getSheet());
  375. sheetComponent.onAttached();
  376. }
  377. });
  378. }
  379. spread.resumePaint();
  380. }
  381. private initSheets() {
  382. let sheets = this.sheets;
  383. let spread = this.spread;
  384. spread.clearSheets();
  385. sheets.forEach((sheetComponent, index) => {
  386. spread.addSheet(index, sheetComponent.getSheet());
  387. sheetComponent.onAttached();
  388. });
  389. // when there is no sheet, add default sheet to spread
  390. if (sheets.length === 0) {
  391. this.spread.addSheet(0, new GC.Spread.Sheets.Worksheet(""));
  392. }
  393. }
  394. private bindCustomEvent(spread: GC.Spread.Sheets.Workbook) {
  395. let customEventNameSpace = '.ng';
  396. let events = ['ValidationError', 'CellClick', 'CellDoubleClick', 'EnterCell',
  397. 'LeaveCell', 'ValueChanged', 'TopRowChanged', 'LeftColumnChanged',
  398. 'InvalidOperation', 'RangeFiltering', 'RangeFiltered', 'TableFiltering',
  399. 'TableFiltered', 'RangeSorting', 'RangeSorted', 'ClipboardChanging',
  400. 'ClipboardChanged', 'ClipboardPasting', 'ClipboardPasted', 'ColumnWidthChanging',
  401. 'ColumnWidthChanged', 'RowHeightChanging', 'RowHeightChanged', 'DragDropBlock',
  402. 'DragDropBlockCompleted', 'DragFillBlock', 'DragFillBlockCompleted', 'EditStarting',
  403. 'EditChange', 'EditEnding', 'EditEnd', 'EditEnded', 'RangeGroupStateChanging',
  404. 'RangeGroupStateChanged', 'SelectionChanging', 'SelectionChanged', 'SheetTabClick',
  405. 'SheetTabDoubleClick', 'SheetNameChanging', 'SheetNameChanged',
  406. 'UserZooming', 'UserFormulaEntered', 'CellChanged', 'ColumnChanged',
  407. 'RowChanged', 'ActiveSheetChanging', 'ActiveSheetChanged',
  408. 'SparklineChanged',
  409. 'RangeChanged', 'ButtonClicked', 'EditorStatusChanged',
  410. 'FloatingObjectChanged', 'FloatingObjectSelectionChanged', 'PictureChanged', 'FloatingObjectRemoving', 'FloatingObjectRemoved', 'PictureSelectionChanged',
  411. 'FloatingObjectLoaded', 'TouchToolStripOpening', 'CommentChanged', 'CommentRemoving', 'CommentRemoved', 'SlicerChanged'];
  412. events.forEach((event) => {
  413. spread.bind(event + customEventNameSpace, (event: any, data: any) => {
  414. let eventType = event.type;
  415. let camelCaseEvent = eventType[0].toLowerCase() + eventType.substr(1);
  416. this[camelCaseEvent].emit(data);
  417. });
  418. });
  419. }
  420. setSpreadOptions() {
  421. let spread = this.spread;
  422. if (!this.spread) {
  423. return;
  424. }
  425. spread.suspendEvent();
  426. spread.suspendPaint();
  427. let options = this.spreadOptions;
  428. options && options.forEach((option) => {
  429. if (option.name === 'name') {
  430. spread.name = option.value;
  431. } else {
  432. spread.options[option.name] = option.value;
  433. }
  434. });
  435. spread.resumePaint();
  436. spread.resumeEvent();
  437. }
  438. ngOnChanges(changes: SimpleChanges) {
  439. let options = [];
  440. for (let changeName in changes) {
  441. let newValue = changes[changeName].currentValue;
  442. if (newValue !== null && newValue !== void 0) {
  443. switch (changeName) {
  444. case 'hostStyle':
  445. this.style = newValue;
  446. break;
  447. case 'hostClass':
  448. break;
  449. default:
  450. options.push({ name: changeName, value: newValue });
  451. }
  452. }
  453. }
  454. this.spreadOptions = options;
  455. this.setSpreadOptions();
  456. }
  457. ngOnDestroy() {
  458. this.spread.destroy();
  459. }
  460. }
  461. @NgModule({
  462. imports: [CommonModule],
  463. declarations: [SpreadSheetsComponent, WorksheetComponent, ColumnComponent],
  464. exports: [SpreadSheetsComponent, WorksheetComponent, ColumnComponent]
  465. })
  466. export class SpreadSheetsModule {
  467. }