목록

SpreadJS의 셀 드롭다운 컨트롤 중 하나는 목록입니다. 이 드롭다운은 JavaScript 코드에서 스타일 속성을 사용하여 정의할 수 있습니다. 이 스타일을 통합 문서의 셀에 적용하면 해당 셀에 정의된 항목이 포함된 목록이 생성됩니다. 아래 스프레드시트에서는 다양한 목록 드롭다운 유형을 보여줍니다.

드롭다운은 개발자에게 특정 속성이 있는 드롭다운 메뉴를 통합 문서의 셀에 추가하는 기능을 제공합니다. 이 드롭다운 메뉴는 드롭다운 메뉴에 사용할 코드를 지정하는 것 이외에 추가 코드가 필요하지 않습니다. 이제 SpreadJS에는 9가지 종류의 드롭다운이 포함됩니다. 이것은 목록입니다. 목록을 열기 전에 셀 스타일에서 옵션 데이터를 설정해야 합니다. 다음 코드와 같이 목록 드롭다운을 사용할 수 있습니다. 또한 다른 옵션을 전달하여 조직 목록 형식을 사용자 정의할 수 있습니다. 목록 옵션 인터페이스는 다음과 같습니다. app.js에서 위 샘플의 코드를 참조할 수 있습니다. 목록 사용자 정의 DOM 요소를 반환하는 함수를 사용하여 목록 항목을 사용자 지정할 수 있으며 클릭하면 콜백 함수는 값을 반환한다. MultiSelect 목록 옵션을 true로 설정하여 목록을 다중 선택으로 설정할 수 있다. valueType이 default 또는 문자열인 경우 쉼표를 구분 문자로 사용한다.
import { Component, NgModule, enableProdMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import GC from '@mescius/spread-sheets'; import { SpreadSheetsModule } from '@mescius/spread-sheets-angular'; import '@mescius/spread-sheets-resources-ko'; GC.Spread.Common.CultureManager.culture("ko-kr"); import './styles.css'; @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent { hostStyle = { width: '100%', height: '100%', overflow: 'hidden', float: 'left' }; initSpread($event: any) { let spread = $event.spread; spread.setSheetCount(2); let sheet = spread.getSheet(0); this.initSheet(sheet, false); sheet = spread.getSheet(1); sheet.name("multi-select list") this.initSheet(sheet, true); spread.commandManager().execute({ cmd: "openList", row: 3, col: 4, sheetName: "Sheet1" }); } initSheet(sheet: GC.Spread.Sheets.WorkSheet, multiSelect: boolean) { sheet.suspendPaint(); // -------------------- Vertical text list --------------------- let verticalStyle = new GC.Spread.Sheets.Style(); verticalStyle.cellButtons = [ { imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openList", useButtonStyle: true, } ]; verticalStyle.dropDowns = [ { type: GC.Spread.Sheets.DropDownType.list, option: { multiSelect: multiSelect, items: [ { text: 'item1', value: 'item1' }, { text: 'item2', value: 'item2' }, { text: 'item3', value: 'item3' }, { text: 'item4', value: 'item4' } ], } } ]; sheet.setText(2, 1, "Vertical text list"); sheet.setStyle(3, 1, verticalStyle); // -------------------- Simple Icon list --------------------- let simpleIconListData = { multiSelect: multiSelect, items: [ { text: 'item1', value: 'item1', icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABWUlEQVQ4T42SrUsEQRjGf68YNIsIomBSsGpSg1XQqMWPaxbBDxTdTV7bOVQ4DXa/ihZBNBsULNdE0GK4YLh/4ILwyg5zy+7c7uGkeed53t++z8wKBUtD+vll2Mrd1CWikWeVvEMNOAZ2Pe1EDHu+vw2gAZoyPbv9bOtMDJmeTKEBt8Cib/agd2JYSjytjYaMonwmX1fu6aVk6yZHwHqiCWMS8RXXyQQasAxcp0wLwICr31HeUtFWxHDjA+LR4wjx+hHDoAaUrclQ1oBvYMTpG2I4zwL2GaKLujUoVamw4wFi2KHT56XCYwZg+wKegDmEKaAP5cE2CHGchotRE8Nk2yVawAFrCBf+W2dqpSQVLnMBbopTYLMAciaGrbRW9Ce+ANMe5FUMMz44HxAyjlIDelxDE2FCIj7+BbBRQlZRl1VYk4irvFi5E7SMGlB1/8F20cV2BHR8DSf+ATHpYBEJcyFZAAAAAElFTkSuQmCC" }, { text: 'item2', value: 'item2', icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABWUlEQVQ4T42SrUsEQRjGf68YNIsIomBSsGpSg1XQqMWPaxbBDxTdTV7bOVQ4DXa/ihZBNBsULNdE0GK4YLh/4ILwyg5zy+7c7uGkeed53t++z8wKBUtD+vll2Mrd1CWikWeVvEMNOAZ2Pe1EDHu+vw2gAZoyPbv9bOtMDJmeTKEBt8Cib/agd2JYSjytjYaMonwmX1fu6aVk6yZHwHqiCWMS8RXXyQQasAxcp0wLwICr31HeUtFWxHDjA+LR4wjx+hHDoAaUrclQ1oBvYMTpG2I4zwL2GaKLujUoVamw4wFi2KHT56XCYwZg+wKegDmEKaAP5cE2CHGchotRE8Nk2yVawAFrCBf+W2dqpSQVLnMBbopTYLMAciaGrbRW9Ce+ANMe5FUMMz44HxAyjlIDelxDE2FCIj7+BbBRQlZRl1VYk4irvFi5E7SMGlB1/8F20cV2BHR8DSf+ATHpYBEJcyFZAAAAAElFTkSuQmCC" }, { text: 'item3', value: 'item3', icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABWUlEQVQ4T42SrUsEQRjGf68YNIsIomBSsGpSg1XQqMWPaxbBDxTdTV7bOVQ4DXa/ihZBNBsULNdE0GK4YLh/4ILwyg5zy+7c7uGkeed53t++z8wKBUtD+vll2Mrd1CWikWeVvEMNOAZ2Pe1EDHu+vw2gAZoyPbv9bOtMDJmeTKEBt8Cib/agd2JYSjytjYaMonwmX1fu6aVk6yZHwHqiCWMS8RXXyQQasAxcp0wLwICr31HeUtFWxHDjA+LR4wjx+hHDoAaUrclQ1oBvYMTpG2I4zwL2GaKLujUoVamw4wFi2KHT56XCYwZg+wKegDmEKaAP5cE2CHGchotRE8Nk2yVawAFrCBf+W2dqpSQVLnMBbopTYLMAciaGrbRW9Ce+ANMe5FUMMz44HxAyjlIDelxDE2FCIj7+BbBRQlZRl1VYk4irvFi5E7SMGlB1/8F20cV2BHR8DSf+ATHpYBEJcyFZAAAAAElFTkSuQmCC" }, { text: 'item4', value: 'item4', icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABWUlEQVQ4T42SrUsEQRjGf68YNIsIomBSsGpSg1XQqMWPaxbBDxTdTV7bOVQ4DXa/ihZBNBsULNdE0GK4YLh/4ILwyg5zy+7c7uGkeed53t++z8wKBUtD+vll2Mrd1CWikWeVvEMNOAZ2Pe1EDHu+vw2gAZoyPbv9bOtMDJmeTKEBt8Cib/agd2JYSjytjYaMonwmX1fu6aVk6yZHwHqiCWMS8RXXyQQasAxcp0wLwICr31HeUtFWxHDjA+LR4wjx+hHDoAaUrclQ1oBvYMTpG2I4zwL2GaKLujUoVamw4wFi2KHT56XCYwZg+wKegDmEKaAP5cE2CHGchotRE8Nk2yVawAFrCBf+W2dqpSQVLnMBbopTYLMAciaGrbRW9Ce+ANMe5FUMMz44HxAyjlIDelxDE2FCIj7+BbBRQlZRl1VYk4irvFi5E7SMGlB1/8F20cV2BHR8DSf+ATHpYBEJcyFZAAAAAElFTkSuQmCC" } ] }; let simpleIconListStyle = new GC.Spread.Sheets.Style(); simpleIconListStyle.cellButtons = [ { imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openList", useButtonStyle: true, } ]; simpleIconListStyle.dropDowns = [ { type: GC.Spread.Sheets.DropDownType.list, option: simpleIconListData } ]; sheet.setText(2, 4, "Vertical text list"); sheet.setStyle(3, 4, simpleIconListStyle); // -------------------- Vertical group list --------------------- let groupListData = { multiSelect: multiSelect, items: [ { text: 'group 1', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.inline }, items: [ { text: 'item1', value: 'item1' }, { text: 'item2', value: 'item2' } ], }, { text: 'group 2', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.inline }, items: [ { text: 'item3', value: 'item3' }, { text: 'item4', value: 'item4' } ] } ] }; let groupListStyle = new GC.Spread.Sheets.Style(); groupListStyle.cellButtons = [ { imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openList", useButtonStyle: true, } ]; groupListStyle.dropDowns = [ { type: GC.Spread.Sheets.DropDownType.list, option: groupListData } ]; sheet.setText(2, 8, "Vertical group list"); sheet.setStyle(3, 8, groupListStyle); // -------------------- Vertical cascade group list --------------------- let cascadeListData = { multiSelect: multiSelect, items: [ { text: 'item1', value: 'item1', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.popup }, items: [ { text: 'sub-item1', value: 'sub-item1' }, { text: 'sub-item2', value: 'sub-item2' } ] }, { text: 'item2', value: 'item2', }, { text: 'item3', value: 'item3', }, { text: 'item4', value: 'item4', } ] }; let verticalCascadeListStyle = new GC.Spread.Sheets.Style(); verticalCascadeListStyle.cellButtons = [ { imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openList", useButtonStyle: true, } ]; verticalCascadeListStyle.dropDowns = [ { type: GC.Spread.Sheets.DropDownType.list, option: cascadeListData } ]; sheet.setText(2, 12, "Vertical cascade group list"); sheet.setStyle(3, 12, verticalCascadeListStyle); // -------------------- Group cascade list --------------------- let groupCascadeListData = { multiSelect: multiSelect, items: [ { text: 'group 1', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.inline }, items: [ { text: 'item1', value: 'item1', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.popup }, items: [ { text: 'sub-item1', value: 'sub-item1' }, { text: 'sub-item2', value: 'sub-item2' } ] }, { text: 'item2', value: 'item2', } ] }, { text: 'group 2', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.inline }, items: [ { text: 'item3', value: 'item3', }, { text: 'item4', value: 'item4', } ] } ] }; let groupCascadeListStyle = new GC.Spread.Sheets.Style(); groupCascadeListStyle.cellButtons = [ { imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openList", useButtonStyle: true, } ]; groupCascadeListStyle.dropDowns = [ { type: GC.Spread.Sheets.DropDownType.list, option: groupCascadeListData } ]; sheet.setText(11, 1, "Group cascade list"); sheet.setStyle(12, 1, groupCascadeListStyle); // -------------------- Tree list --------------------- let treeListData = { multiSelect: multiSelect, items: [ { text: 'group 1', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.tree, collapsible: true }, items: [ { text: 'sub group 1-1', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.tree, collapsible: true }, items: [ { text: 'sub group item1', value: 'subGroupItem1' }, { text: 'sub group item2', value: 'subGroupItem2' } ] }, { text: 'sub group 1-2', value: 'subGroup12' } ], }, { text: 'group 2', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.tree }, items: [ { text: 'sub group 2-1', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.tree }, items: [ { text: 'sub group item3', value: 'subGroupItem3' }, { text: 'sub group item4', value: 'subGroupItem5' } ] }, { text: 'sub group 2-2', value: 'subGroup22' } ], }, ] }; let treeListStyle = new GC.Spread.Sheets.Style(); treeListStyle.cellButtons = [ { imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openList", useButtonStyle: true, } ]; treeListStyle.dropDowns = [ { type: GC.Spread.Sheets.DropDownType.list, option: treeListData } ]; sheet.setText(11, 4, "Vertical tree list"); sheet.setStyle(12, 4, treeListStyle); // -------------------- Horizontal group list --------------------- let horizontalGroupListData = { multiSelect: multiSelect, layout: { direction: GC.Spread.Sheets.LayoutDirection.horizontal }, items: [ { layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.inline, direction: GC.Spread.Sheets.LayoutDirection.horizontal }, text: 'group 1', items: [ { text: 'item1', value: 'item1' }, { text: 'item2', value: 'item2' } ], }, { text: 'group 2', layout: { displayAs: GC.Spread.Sheets.LayoutDisplayAs.inline }, items: [ { text: 'item3', value: 'item3' }, { text: 'item4', value: 'item4' } ] } ] }; let horizontalGroupListStyle = new GC.Spread.Sheets.Style(); horizontalGroupListStyle.cellButtons = [ { imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openList", useButtonStyle: true, } ]; horizontalGroupListStyle.dropDowns = [ { type: GC.Spread.Sheets.DropDownType.list, option: horizontalGroupListData } ]; sheet.setText(11, 8, "Vertical tree list"); sheet.setStyle(12, 8, horizontalGroupListStyle); // -------------------- Custom list --------------------- // This part just shows how to custom a list. (not a real color selector) let colorListData = { multiSelect: multiSelect, onItemSelected: colorClicked, items: [ { text: 'Theme Colors', layout: { direction: GC.Spread.Sheets.LayoutDirection.horizontal, displayAs: GC.Spread.Sheets.LayoutDisplayAs.inline }, items: generateThemeColors }, { text: 'Standard Colors', layout: { direction: GC.Spread.Sheets.LayoutDirection.horizontal, displayAs: GC.Spread.Sheets.LayoutDisplayAs.inline }, items: generateStandardColors }, { text: 'No Color', value: 'nocolor' }, { text: 'More Colors...', value: 'morecolors', icon: 'more-color-icon' } ] }; let customStyle = new GC.Spread.Sheets.Style(); customStyle.cellButtons = [ { imageType: GC.Spread.Sheets.ButtonImageType.dropdown, command: "openList", useButtonStyle: true, } ]; customStyle.dropDowns = [ { type: GC.Spread.Sheets.DropDownType.list, option: colorListData } ]; sheet.setText(11, 12, "Custom list"); sheet.setStyle(12, 12, customStyle); // spread.commandManager().execute({cmd:"openList",row:12,col:12,sheetName:"List"}); sheet.resumePaint(); // spread.commandManager().execute({cmd:"openList",row:3,col:1,sheetName:"Sheet1"}); // spread.commandManager().execute({cmd:"openList",row:3,col:8,sheetName:"Sheet1"}); // spread.commandManager().execute({cmd:"openList",row:3,col:12,sheetName:"Sheet1"}); // spread.commandManager().execute({cmd:"openList",row:12,col:1,sheetName:"Sheet1"}); // spread.commandManager().execute({cmd:"openList",row:12,col:4,sheetName:"Sheet1"}); // spread.commandManager().execute({cmd:"openList",row:12,col:8,sheetName:"Sheet1"}); } } function generateThemeColors() { return generateColors(10, 0, 16777215) } function generateStandardColors() { return generateColors(10, 0, 65526) } function colorClicked(event: Event) { let target = <HTMLElement>event.target; if (target && target.classList.contains("custom-color-block")) { let color = target.style.backgroundColor; return color; } return null; } function pad(pad: string, str: string, padLeft: boolean) { if (typeof str === "undefined") { return pad; } if (padLeft) { return (pad + str).slice(-pad.length); } else { return (str + pad).substring(0, pad.length); } } function generateColors(count: number, start: number, stop: number) { let div = document.createElement("div"); div.style.width = "140px"; let step = (stop - start) / count | 0; for (let i = start, index = 0; i < stop && index < count; i += step, index++) { let item = document.createElement("div"); item.style.backgroundColor = `#${pad('000000', i.toString(16), true)}`; item.style.width = '12px'; item.style.height = '12px'; item.style.border = '1px solid #c3c3c3'; item.classList.add("custom-color-block"); div.appendChild(item); } return div; } @NgModule({ imports: [BrowserModule, SpreadSheetsModule], declarations: [AppComponent], exports: [AppComponent], bootstrap: [AppComponent] }) export class AppModule { } enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule);
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/angular/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <!-- Polyfills --> <script src="$DEMOROOT$/ko/angular/node_modules/core-js/client/shim.min.js"></script> <script src="$DEMOROOT$/ko/angular/node_modules/zone.js/fesm2015/zone.min.js"></script> <!-- SystemJS --> <script src="$DEMOROOT$/ko/angular/node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.import('@angular/compiler'); System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('$DEMOROOT$/ko/lib/angular/license.ts'); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html>
<div class="sample-tutorial"> <gc-spread-sheets [hostStyle]="hostStyle" (workbookInitialized)="initSpread($event)"> </gc-spread-sheets> </div>
.sample-tutorial { position: relative; width: 100%; height: 100%; overflow: hidden; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }
(function (global) { System.config({ transpiler: 'ts', typescriptOptions: { tsconfig: true }, meta: { 'typescript': { "exports": "ts" }, '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { 'core-js': 'npm:core-js/client/shim.min.js', 'zone': 'npm:zone.js/fesm2015/zone.min.js', 'rxjs': 'npm:rxjs/dist/bundles/rxjs.umd.min.js', '@angular/core': 'npm:@angular/core/fesm2022', '@angular/common': 'npm:@angular/common/fesm2022/common.mjs', '@angular/compiler': 'npm:@angular/compiler/fesm2022/compiler.mjs', '@angular/platform-browser': 'npm:@angular/platform-browser/fesm2022/platform-browser.mjs', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/fesm2022/platform-browser-dynamic.mjs', '@angular/common/http': 'npm:@angular/common/fesm2022/http.mjs', '@angular/router': 'npm:@angular/router/fesm2022/router.mjs', '@angular/forms': 'npm:@angular/forms/fesm2022/forms.mjs', 'jszip': 'npm:jszip/dist/jszip.min.js', 'typescript': 'npm:typescript/lib/typescript.js', 'ts': './plugin.js', 'tslib':'npm:tslib/tslib.js', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js', '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-resources-ko': 'npm:@mescius/spread-sheets-resources-ko/index.js', '@mescius/spread-sheets-angular': 'npm:@mescius/spread-sheets-angular/fesm2020/mescius-spread-sheets-angular.mjs', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'ts' }, rxjs: { defaultExtension: 'js' }, "node_modules": { defaultExtension: 'js' }, "node_modules/@angular": { defaultExtension: 'mjs' }, "@mescius/spread-sheets-angular": { defaultExtension: 'mjs' }, '@angular/core': { defaultExtension: 'mjs', main: 'core.mjs' } } }); })(this);