이 가이드는 @angular/cli의 시작 패키지를 기준으로 작성되었습니다.
아래 가이드의 완성본은 시작 패키지 문서에서 확인할 수 있습니다.
Angular-Material 을 적용한 가이드는 데모 패키지에서 확인할 수 있습니다.
사전 설정
CLI 설치
npm install -g @angular/cli
프로젝트 생성
ng new <project_dir>
패키지 설치
cd <project_dir>yarn add @ibsheet/loader# using npm# npm i -S @ibsheet/loader
tsconfig.app.json 설정
@ibsheet/loader는 내부적으로 Node.js의 events 모듈(EventEmitter)을 사용합니다. Angular CLI가 생성하는 기본 tsconfig.app.json은 types 옵션이 빈 배열([])로 설정되어 있어 타입 선언을 찾지 못해 컴파일 에러(TS7016)가 발생합니다. types 배열에 "node"를 추가해주세요.
tsconfig.app.json
{"extends": "./tsconfig.json","compilerOptions": {"outDir": "./out-tsc/app","types": ["node"]},...}
IBSheet 라이브러리
만약 서버 URL을 사용한다면 이 단계는 생략합니다. (예: https://demo.ibsheet.com/ibsheet/v8/samples/customer-sample/assets/ibsheet/와 같은 데모 서버 URL은 학습용으로만 사용하고, 실제 서비스에서는 라이브러리를 프로젝트에 포함해 배포하는 것을 권장합니다.)
프로젝트 폴더의 public 폴더에 ibsheet 라이브러리를 복사합니다.
├── public/| └── ibsheet/| ├── css/| ├── locale/| ├── fonts/| ├── ibsheet.js| └── ibleaders.js
개발서버 실행
yarn start# using npm# npm start
메인 컴포넌트
메인 컴포넌트 혹은 모듈에서 사용할 라이브러리들을 설정(등록)합니다.
main.ts
src/main.ts
import { bootstrapApplication } from '@angular/platform-browser';import { appConfig } from './app/app.config';import { App } from './app/app';bootstrapApplication(App, appConfig).catch((err) => console.error(err));
app.config.ts
src/app/app.config.ts
import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core';import { provideRouter } from '@angular/router';import { routes } from './app.routes';export const appConfig: ApplicationConfig = {providers: [provideBrowserGlobalErrorListeners(),provideZoneChangeDetection({ eventCoalescing: true }),provideRouter(routes)]};
app.ts
src/app/app.ts
import { Component } from '@angular/core';import { RouterOutlet, RouterLink } from '@angular/router';import loader from '@ibsheet/loader';const ibsheetLib = {name: 'ibsheet',baseUrl: '/ibsheet',main: 'ibsheet.js',locales: ['en', 'ko'],plugins: ['excel', 'common', 'dialog']}// 로더 configloader.config({registry: [ibsheetLib]});// loader.load()@Component({selector: 'app-root',imports: [RouterOutlet, RouterLink],templateUrl: './app.html',styleUrl: './app.css'})export class App {protected title = 'loader-ng-starter';loaderVersion = loader.version;}
app.html
src/app/app.html
<p>@ibsheet/loader v{{ loaderVersion }}</p><nav><ul><li><a [routerLink]="['/home']">Home</a></li><li><a [routerLink]="['/page1']">Page1</a></li><li><a [routerLink]="['/page2']">Page2</a></li></ul></nav><router-outlet></router-outlet>
샘플 공유 데이터
각 컴포넌트에서 사용할 공용 샘플 데이터 파일을 만듭니다.
서브 컴포넌트
src/app/homesrc/app/page1src/app/page2
cd src/appng generate component homeng generate component page1ng generate component page2
Home
홈 화면입니다.
src/app/home/home.html
<div style="text-align:center"><h1>{{ title }}!</h1><img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg=="></div>
src/app/home/home.ts
import { Component } from '@angular/core';@Component({selector: 'app-home',imports: [],templateUrl: './home.html',styleUrl: './home.css'})export class Home {title = 'IBSheetLoader for Angular';}
Page1
컴포넌트 마운트시 첫 번째 샘플 데이터로 시트를 생성합니다.
src/app/page1/page1.html
<p>page1 works!</p><div id="sheetContainer"></div>
src/app/page1/page1.ts
import { Component, OnInit, OnDestroy } from '@angular/core';import loader from '@ibsheet/loader';import { SheetSampleData } from '../shared/ibsheet-data';@Component({selector: 'app-page1',imports: [],templateUrl: './page1.html',styleUrl: './page1.css'})export class Page1 implements OnInit, OnDestroy {sheetId = '';ngOnInit(): void {const A = this;const { options, data } = SheetSampleData[0];loader.createSheet({id: this.sheetId,el: 'sheetContainer',options,data}).then((sheet: { id: any; }) => {A.sheetId = sheet.id;// 주의: 해당 구간에서 데이터 조회를 하면 안됩니다. 데이터 조회는 onRenderFirstFinish 이벤트에서 실행해야합니다.console.log('created sheet', sheet.id);});}ngOnDestroy(): void {// loader.removeSheet(this.sheetId);}}
Page2
두 번째 샘플 데이터로 시트를 생성합니다. 컴포넌트가 제거될 때, 해당 테이블도 제거합니다.
src/app/page2/page2.html
<p>page2 works!</p><div id="sheetContainer"></div>
src/app/page2/page2.ts
import { Component } from '@angular/core';import loader from '@ibsheet/loader';import { SheetSampleData } from '../shared/ibsheet-data';@Component({selector: 'app-page2',imports: [],templateUrl: './page2.html',styleUrl: './page2.css'})export class Page2 {sheetId = '';ngOnInit(): void {const A = this;const { options, data } = SheetSampleData[1];loader.createSheet({el: 'sheetContainer',options,data}).then((sheet: { id: any; }) => {A.sheetId = sheet.id;// 주의: 해당 구간에서 데이터 조회를 하면 안됩니다. 데이터 조회는 onRenderFirstFinish 이벤트에서 실행해야합니다.console.log('created sheet', sheet.id);});}ngOnDestroy(): void {loader.removeSheet(this.sheetId);}}
라우터 설정하기
이상 만들었던 서브 컴포넌트들을 라우터 구성에 추가합니다.
app.routes.ts
src/app/app.routes.ts
import { Routes } from '@angular/router';import { Home } from './home/home';import { Page1 } from './page1/page1';import { Page2 } from './page2/page2';export const routes: Routes = [{path: 'home', component: Home},{path: 'page1', component: Page1},{path: 'page2', component: Page2}];
Package.json
"dependencies": {"@ibsheet/loader": "^1.3.4","@angular/common": "^20.1.0","@angular/compiler": "^20.1.0","@angular/core": "^20.1.0","@angular/forms": "^20.1.0","@angular/platform-browser": "^20.1.0","@angular/router": "^20.1.0","rxjs": "~7.8.0","tslib": "^2.3.0","zone.js": "~0.15.0"},
시작 패키지
위의 가이드 내용을 바탕으로 구성한 소스코드 저장소를 다음 페이지에서 확인할 수 있습니다.