gc.spread.sheets.angular.13.1.0.ts 21 KB

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