@simplysm/excel 14.0.50 → 14.0.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplysm/excel",
3
- "version": "14.0.50",
3
+ "version": "14.0.52",
4
4
  "description": "심플리즘 패키지 - 엑셀 (neutral)",
5
5
  "author": "심플리즘",
6
6
  "license": "Apache-2.0",
@@ -14,8 +14,7 @@
14
14
  "types": "./dist/index.d.ts",
15
15
  "files": [
16
16
  "dist",
17
- "src",
18
- "docs"
17
+ "src"
19
18
  ],
20
19
  "sideEffects": false,
21
20
  "devDependencies": {
@@ -24,6 +23,6 @@
24
23
  "dependencies": {
25
24
  "mime": "^4.1.0",
26
25
  "zod": "^4.3.6",
27
- "@simplysm/core-common": "14.0.50"
26
+ "@simplysm/core-common": "14.0.52"
28
27
  }
29
28
  }
package/README.md DELETED
@@ -1,127 +0,0 @@
1
- # @simplysm/excel
2
-
3
- Excel 워크북(xlsx) 읽기/쓰기 라이브러리. DOM 의존성이 없어 Node.js와 브라우저 양쪽에서 동작하는 neutral 패키지다. Lazy Loading 아키텍처로 대용량 파일도 메모리 효율적으로 처리한다.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @simplysm/excel
9
- ```
10
-
11
- ## API Overview
12
-
13
- ### Core Classes
14
-
15
- | Entry | Kind | Description |
16
- |-------|------|-------------|
17
- | [`ExcelWorkbook`](./docs/core-classes/excel-workbook.md) | class | Excel 워크북 진입점. 워크시트 생성/조회, 바이트 내보내기, ZIP 리소스 관리 |
18
- | [`ExcelWorksheet`](./docs/core-classes/excel-worksheet.md) | class | 워크시트. 셀/행/열 접근, 행/셀 복사, 데이터 테이블 읽기, 이미지 삽입, 시트명 변경 |
19
- | [`ExcelCell`](./docs/core-classes/excel-cell.md) | class | 개별 셀. 값/수식 읽기/쓰기, 스타일 설정, 셀 병합 |
20
- | [`ExcelRow`](./docs/core-classes/excel-row.md) | class | 워크시트 행. 셀 접근, 행 전체 셀 조회 |
21
- | [`ExcelCol`](./docs/core-classes/excel-col.md) | class | 워크시트 열. 셀 접근, 열 너비 설정 |
22
-
23
- ### Wrapper
24
-
25
- | Entry | Kind | Description |
26
- |-------|------|-------------|
27
- | [`ExcelWrapper`](./docs/wrapper/excel-wrapper.md) | class | Zod 스키마 기반 타입 안전한 Excel 읽기/쓰기. 헤더 자동 생성, 유효성 검사, 필수 필드 강조 |
28
-
29
- ### Utilities
30
-
31
- | Entry | Kind | Description |
32
- |-------|------|-------------|
33
- | [`ExcelUtils`](./docs/utilities/excel-utils.md) | class | 셀 주소 변환 (좌표↔문자열), 날짜↔숫자 변환, 숫자 형식 매핑 (정적 메서드) |
34
-
35
- ### Types
36
-
37
- | Entry | Kind | Description |
38
- |-------|------|-------------|
39
- | [`ExcelValueType`](./docs/types/excel-value-type.md) | type | 셀 값 타입: number, string, DateOnly, DateTime, Time, boolean, undefined. `ExcelCellType` 포함 |
40
- | [`ExcelAddressPoint`](./docs/types/excel-address-point.md) | interface | 셀 좌표 (0 기반 r, c). `ExcelAddressRangePoint` 포함 |
41
- | [`ExcelStyleOptions`](./docs/types/excel-style-options.md) | interface | 셀 스타일 옵션 (배경색, 테두리, 정렬, 숫자 형식). `ExcelNumberFormat`, `ExcelBorderPosition`, `ExcelHorizontalAlign`, `ExcelVerticalAlign` 포함 |
42
- | [`ExcelXml`](./docs/types/excel-xml.md) | interface | XML 처리 클래스가 구현하는 인터페이스 (내부용) |
43
- | [`ExcelXmlContentTypeData`](./docs/types/excel-xml-content-type-data.md) | interface | `[Content_Types].xml` 데이터 구조 (내부용) |
44
- | [`ExcelXmlRelationshipData`](./docs/types/excel-xml-relationship-data.md) | interface | `*.rels` 파일 데이터 구조 (내부용). `ExcelRelationshipData` 포함 |
45
- | [`ExcelXmlWorkbookData`](./docs/types/excel-xml-workbook-data.md) | interface | `workbook.xml` 데이터 구조 (내부용) |
46
- | [`ExcelXmlWorksheetData`](./docs/types/excel-xml-worksheet-data.md) | interface | `worksheet*.xml` 데이터 구조 (내부용). `ExcelRowData`, `ExcelCellData` 포함 |
47
- | [`ExcelXmlDrawingData`](./docs/types/excel-xml-drawing-data.md) | interface | `drawing*.xml` 데이터 구조 (내부용) |
48
- | [`ExcelXmlSharedStringData`](./docs/types/excel-xml-shared-string-data.md) | interface | `sharedStrings.xml` 데이터 구조 (내부용). `ExcelXmlSharedStringDataSi`, `ExcelXmlSharedStringDataText` 포함 |
49
- | [`ExcelXmlStyleData`](./docs/types/excel-xml-style-data.md) | interface | `styles.xml` 데이터 구조 (내부용). `ExcelXmlStyleDataXf`, `ExcelXmlStyleDataFill`, `ExcelXmlStyleDataBorder` 포함 |
50
-
51
- ## Usage Examples
52
-
53
- ### 새 Excel 파일 생성 및 저장
54
-
55
- ```typescript
56
- import { ExcelWorkbook } from "@simplysm/excel";
57
-
58
- const wb = new ExcelWorkbook();
59
- try {
60
- const ws = await wb.addWorksheet("Sheet1");
61
-
62
- // 헤더 행
63
- await ws.cell(0, 0).setValue("이름");
64
- await ws.cell(0, 1).setValue("나이");
65
-
66
- // 데이터 행
67
- await ws.cell(1, 0).setValue("김철수");
68
- await ws.cell(1, 1).setValue(30);
69
-
70
- const bytes = await wb.toBytes();
71
- // 파일 저장 또는 전송
72
- } finally {
73
- await wb.close();
74
- }
75
- ```
76
-
77
- ### 기존 Excel 파일 읽기
78
-
79
- ```typescript
80
- import { ExcelWorkbook } from "@simplysm/excel";
81
-
82
- const bytes = /* 파일 바이트 배열 */;
83
- const wb = new ExcelWorkbook(bytes);
84
- try {
85
- // 시트명 또는 인덱스(0 기반)로 조회
86
- const ws = await wb.getWorksheet(0);
87
-
88
- // 개별 셀 읽기
89
- const value = await ws.cell(0, 0).getValue();
90
-
91
- // 전체 데이터 테이블 읽기 (첫 행이 헤더)
92
- const table = await ws.getDataTable();
93
- } finally {
94
- await wb.close();
95
- }
96
- ```
97
-
98
- ### Zod 스키마 기반 타입 안전한 작업
99
-
100
- ```typescript
101
- import { ExcelWrapper } from "@simplysm/excel";
102
- import { z } from "zod";
103
-
104
- const schema = z.object({
105
- name: z.string().describe("이름"),
106
- age: z.number().describe("나이"),
107
- email: z.string().optional().describe("이메일"),
108
- });
109
-
110
- const wrapper = new ExcelWrapper(schema);
111
-
112
- // 레코드 배열을 Excel로 쓰기
113
- const records = [
114
- { name: "김철수", age: 30, email: "kim@example.com" },
115
- { name: "이영희", age: 28 },
116
- ];
117
- const wb = await wrapper.write("사람", records);
118
- try {
119
- const bytes = await wb.toBytes();
120
- } finally {
121
- await wb.close();
122
- }
123
-
124
- // Excel 파일을 레코드 배열로 읽기 (유효성 검사 포함)
125
- const bytes = /* 파일 바이트 배열 */;
126
- const data = await wrapper.read(bytes, "사람");
127
- ```
@@ -1,73 +0,0 @@
1
- # ExcelCell
2
-
3
- Excel 셀을 나타내는 클래스. 값 읽기/쓰기, 수식, 스타일, 셀 병합 기능을 제공한다.
4
-
5
- 모든 메서드가 `async`인 이유는 셀 타입에 따라 필요한 XML만 선택적으로 로드하는 Lazy Loading 아키텍처 때문이다. 문자열 셀은 `sharedStrings.xml`을 로드하고, 숫자 셀은 로드하지 않는다.
6
-
7
- ```typescript
8
- export class ExcelCell {
9
- readonly addr: ExcelAddressPoint;
10
-
11
- constructor(zipCache: ZipCache, targetFileName: string, r: number, c: number);
12
-
13
- // Value
14
- async setValue(val: ExcelValueType): Promise<void>;
15
- async getValue(): Promise<ExcelValueType>;
16
- async setFormula(val: string | undefined): Promise<void>;
17
- async getFormula(): Promise<string | undefined>;
18
-
19
- // Merge
20
- async merge(r: number, c: number): Promise<void>;
21
-
22
- // Style
23
- async getStyleId(): Promise<string | undefined>;
24
- async setStyleId(styleId: string | undefined): Promise<void>;
25
- async setStyle(opts: ExcelStyleOptions): Promise<void>;
26
- }
27
- ```
28
-
29
- ## Members
30
-
31
- | Member | Kind | Type | Description |
32
- |--------|------|------|-------------|
33
- | `addr` | property | `ExcelAddressPoint` | 셀 주소 (0 기반 행/열 인덱스, read-only) |
34
- | `setValue` | method | `(val: ExcelValueType) => Promise<void>` | 셀 값 설정. `undefined` 전달 시 셀 삭제. `DateOnly`/`DateTime`/`Time`은 Excel 날짜 숫자로 변환하고 numFmt 설정 |
35
- | `getValue` | method | `() => Promise<ExcelValueType>` | 셀 값 반환. 비어있는 셀은 `undefined` 반환. 셀 타입과 스타일에 따라 적절한 JS 타입으로 변환 |
36
- | `setFormula` | method | `(val: string \| undefined) => Promise<void>` | 셀 수식 설정. `undefined` 전달 시 수식 제거 |
37
- | `getFormula` | method | `() => Promise<string \| undefined>` | 셀 수식 반환. 수식 없으면 `undefined` 반환 |
38
- | `merge` | method | `(r: number, c: number) => Promise<void>` | 현재 셀에서 지정된 끝 좌표까지 셀 병합 |
39
- | `getStyleId` | method | `() => Promise<string \| undefined>` | 셀의 스타일 ID 반환. 스타일 없으면 `undefined` 반환 |
40
- | `setStyleId` | method | `(styleId: string \| undefined) => Promise<void>` | 셀의 스타일 ID 직접 설정 |
41
- | `setStyle` | method | `(opts: ExcelStyleOptions) => Promise<void>` | 셀 스타일 설정. 기존 스타일이 있으면 클론 후 병합 |
42
-
43
- ## Usage
44
-
45
- ```typescript
46
- // 값 설정/읽기
47
- await ws.cell(0, 0).setValue("텍스트");
48
- await ws.cell(0, 1).setValue(42);
49
- await ws.cell(0, 2).setValue(new DateOnly(2024, 6, 15));
50
- await ws.cell(0, 3).setValue(true);
51
- await ws.cell(0, 4).setValue(undefined); // 셀 삭제
52
-
53
- const val = await ws.cell(0, 0).getValue(); // "텍스트"
54
-
55
- // 수식
56
- await ws.cell(1, 0).setFormula("SUM(A1:A10)");
57
- const formula = await ws.cell(1, 0).getFormula(); // "SUM(A1:A10)"
58
-
59
- // 셀 병합 (A1:C3 병합)
60
- await ws.cell(0, 0).merge(2, 2);
61
-
62
- // 스타일
63
- await ws.cell(0, 0).setStyle({
64
- background: "00FFFF00", // 노란색 배경
65
- border: ["left", "right", "top", "bottom"],
66
- horizontalAlign: "center",
67
- verticalAlign: "center",
68
- numberFormat: "number",
69
- });
70
-
71
- // 커스텀 formatCode
72
- await ws.cell(0, 0).setStyle({ numberFormatCode: "0.000000" });
73
- ```
@@ -1,36 +0,0 @@
1
- # ExcelCol
2
-
3
- Excel 워크시트의 열을 나타내는 클래스. 셀 접근 및 열 너비 설정 기능을 제공한다.
4
-
5
- ```typescript
6
- export class ExcelCol {
7
- constructor(zipCache: ZipCache, targetFileName: string, c: number, cellFactory: (r: number) => ExcelCell);
8
-
9
- cell(r: number): ExcelCell;
10
- async getCells(): Promise<ExcelCell[]>;
11
- async setWidth(size: number): Promise<void>;
12
- }
13
- ```
14
-
15
- ## Members
16
-
17
- | Member | Kind | Type | Description |
18
- |--------|------|------|-------------|
19
- | `cell` | method | `(r: number) => ExcelCell` | 지정된 행 인덱스의 셀 반환 (0 기반) |
20
- | `getCells` | method | `() => Promise<ExcelCell[]>` | 열의 모든 셀 반환. 데이터 범위 내의 모든 행에 대한 셀이 포함된다 |
21
- | `setWidth` | method | `(size: number) => Promise<void>` | 열 너비 설정 |
22
-
23
- ## Usage
24
-
25
- ```typescript
26
- const col = ws.col(1); // B열
27
-
28
- // 특정 셀 접근
29
- const cell = col.cell(0); // B1 셀
30
-
31
- // 열의 모든 셀
32
- const cells = await col.getCells();
33
-
34
- // 열 너비 설정
35
- await ws.col(0).setWidth(20);
36
- ```
@@ -1,34 +0,0 @@
1
- # ExcelRow
2
-
3
- Excel 워크시트의 행을 나타내는 클래스. 셀 접근 기능을 제공한다.
4
-
5
- ```typescript
6
- export class ExcelRow {
7
- constructor(zipCache: ZipCache, targetFileName: string, r: number, cellFactory: (c: number) => ExcelCell);
8
-
9
- cell(c: number): ExcelCell;
10
- async getCells(): Promise<ExcelCell[]>;
11
- }
12
- ```
13
-
14
- ## Members
15
-
16
- | Member | Kind | Type | Description |
17
- |--------|------|------|-------------|
18
- | `cell` | method | `(c: number) => ExcelCell` | 지정된 열 인덱스의 셀 반환 (0 기반) |
19
- | `getCells` | method | `() => Promise<ExcelCell[]>` | 행의 모든 셀 반환. 데이터 범위 내의 모든 열에 대한 셀이 포함된다 |
20
-
21
- ## Usage
22
-
23
- ```typescript
24
- const row = ws.row(0);
25
-
26
- // 특정 셀 접근
27
- const cell = row.cell(2); // C열 셀
28
-
29
- // 행의 모든 셀
30
- const cells = await row.getCells();
31
- for (const cell of cells) {
32
- const val = await cell.getValue();
33
- }
34
- ```
@@ -1,59 +0,0 @@
1
- # ExcelWorkbook
2
-
3
- Excel 워크북 처리 클래스. 내부적으로 ZIP 리소스를 관리하므로 사용 후 반드시 `try-finally` 블록에서 `close()`를 호출해야 한다.
4
-
5
- 대용량 Excel 파일의 메모리 효율을 위해 Lazy Loading 아키텍처를 채택한다. ZIP 내부의 XML은 접근 시점에만 읽고 파싱한다.
6
-
7
- ```typescript
8
- export class ExcelWorkbook {
9
- readonly zipCache: ZipCache;
10
-
11
- constructor(arg?: Blob | Bytes);
12
-
13
- async getWorksheetNames(): Promise<string[]>;
14
- async addWorksheet(name: string): Promise<ExcelWorksheet>;
15
- async getWorksheet(nameOrIndex: string | number): Promise<ExcelWorksheet>;
16
- async toBytes(): Promise<Bytes>;
17
- async toBlob(): Promise<Blob>;
18
- async close(): Promise<void>;
19
- }
20
- ```
21
-
22
- ## Members
23
-
24
- | Member | Kind | Type | Description |
25
- |--------|------|------|-------------|
26
- | `zipCache` | property | `ZipCache` | ZIP 캐시 인스턴스 (read-only) |
27
- | `constructor` | method | `(arg?: Blob \| Bytes) => ExcelWorkbook` | `arg` 생략 시 새 워크북 생성, 전달 시 기존 파일 읽기 |
28
- | `getWorksheetNames` | method | `() => Promise<string[]>` | 워크북의 모든 워크시트 이름 반환 |
29
- | `addWorksheet` | method | `(name: string) => Promise<ExcelWorksheet>` | 새 워크시트 생성하여 반환 |
30
- | `getWorksheet` | method | `(nameOrIndex: string \| number) => Promise<ExcelWorksheet>` | 이름 또는 0 기반 인덱스로 워크시트 조회. 찾을 수 없으면 에러 발생 |
31
- | `toBytes` | method | `() => Promise<Bytes>` | 워크북을 `Bytes`(Uint8Array)로 내보내기 |
32
- | `toBlob` | method | `() => Promise<Blob>` | 워크북을 `Blob`으로 내보내기. MIME 타입: `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
33
- | `close` | method | `() => Promise<void>` | ZIP 리더와 내부 캐시 정리. 이미 닫힌 워크북에 대해 호출해도 안전하다 (no-op). 닫힌 후 메서드 호출 시 에러 발생 |
34
-
35
- ## Usage
36
-
37
- ```typescript
38
- import { ExcelWorkbook } from "@simplysm/excel";
39
-
40
- // 신규 생성
41
- const wb = new ExcelWorkbook();
42
- try {
43
- const ws = await wb.addWorksheet("Sheet1");
44
- await ws.cell(0, 0).setValue("값");
45
- const bytes = await wb.toBytes();
46
- } finally {
47
- await wb.close();
48
- }
49
-
50
- // 기존 파일 읽기 (Uint8Array 또는 Blob)
51
- const wb2 = new ExcelWorkbook(bytes);
52
- try {
53
- const ws = await wb2.getWorksheet(0); // 0 기반 인덱스
54
- const ws2 = await wb2.getWorksheet("Sheet1"); // 시트명으로도 조회 가능
55
- const names = await wb2.getWorksheetNames();
56
- } finally {
57
- await wb2.close();
58
- }
59
- ```
@@ -1,139 +0,0 @@
1
- # ExcelWorksheet
2
-
3
- Excel 워크시트를 나타내는 클래스. 셀 접근, 행/열 복사, 데이터 테이블 처리, 이미지 삽입, 뷰 설정 기능을 제공한다.
4
-
5
- ```typescript
6
- export class ExcelWorksheet {
7
- constructor(zipCache: ZipCache, relId: number, targetFileName: string);
8
-
9
- // Name
10
- async getName(): Promise<string>;
11
- async setName(newName: string): Promise<void>;
12
-
13
- // Cell Access (0 기반)
14
- row(r: number): ExcelRow;
15
- cell(r: number, c: number): ExcelCell;
16
- col(c: number): ExcelCol;
17
-
18
- // Copy
19
- async copyRowStyle(srcR: number, targetR: number): Promise<void>;
20
- async copyCellStyle(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint): Promise<void>;
21
- async copyRow(srcR: number, targetR: number): Promise<void>;
22
- async copyCell(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint): Promise<void>;
23
- async insertCopyRow(srcR: number, targetR: number): Promise<void>;
24
-
25
- // Range
26
- async getRange(): Promise<ExcelAddressRangePoint>;
27
- async getCells(): Promise<ExcelCell[][]>;
28
-
29
- // Data
30
- async getDataTable(opt?: {
31
- headerRowIndex?: number;
32
- checkEndColIndex?: number;
33
- usableHeaderNameFn?: (headerName: string) => boolean;
34
- }): Promise<Record<string, ExcelValueType>[]>;
35
- async setDataMatrix(matrix: ExcelValueType[][]): Promise<void>;
36
- async setRecords(records: Record<string, ExcelValueType>[]): Promise<void>;
37
-
38
- // View
39
- async setZoom(percent: number): Promise<void>;
40
- async freezeAt(point: { r?: number; c?: number }): Promise<void>;
41
-
42
- // Image
43
- async addImage(opts: {
44
- bytes: Bytes;
45
- ext: string;
46
- from: { r: number; c: number; rOff?: number | string; cOff?: number | string };
47
- to?: { r: number; c: number; rOff?: number | string; cOff?: number | string };
48
- }): Promise<void>;
49
- }
50
- ```
51
-
52
- ## Members
53
-
54
- | Member | Kind | Type | Description |
55
- |--------|------|------|-------------|
56
- | `getName` | method | `() => Promise<string>` | 워크시트 이름 반환 |
57
- | `setName` | method | `(newName: string) => Promise<void>` | 워크시트 이름 변경 |
58
- | `row` | method | `(r: number) => ExcelRow` | 행 객체 반환 (0 기반) |
59
- | `cell` | method | `(r: number, c: number) => ExcelCell` | 셀 객체 반환 (0 기반). 동일 좌표에 대해 항상 동일한 인스턴스 반환 |
60
- | `col` | method | `(c: number) => ExcelCol` | 열 객체 반환 (0 기반) |
61
- | `copyRowStyle` | method | `(srcR: number, targetR: number) => Promise<void>` | 원본 행의 스타일을 대상 행으로 복사. 데이터 범위 내 모든 열에 적용 |
62
- | `copyCellStyle` | method | `(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint) => Promise<void>` | 원본 셀의 스타일을 대상 셀로 복사 |
63
- | `copyRow` | method | `(srcR: number, targetR: number) => Promise<void>` | 원본 행을 대상 행으로 복사 (덮어쓰기) |
64
- | `copyCell` | method | `(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint) => Promise<void>` | 원본 셀을 대상 셀로 복사 |
65
- | `insertCopyRow` | method | `(srcR: number, targetR: number) => Promise<void>` | 원본 행을 대상 위치에 삽입 복사. 대상 이하 행은 한 칸 아래로 이동. 병합 셀 자동 처리 |
66
- | `getRange` | method | `() => Promise<ExcelAddressRangePoint>` | 워크시트의 데이터 범위 반환 |
67
- | `getCells` | method | `() => Promise<ExcelCell[][]>` | 모든 셀을 2차원 배열로 반환 |
68
- | `getDataTable` | method | `(opt?) => Promise<Record<string, ExcelValueType>[]>` | 워크시트 데이터를 테이블(레코드 배열)로 반환 |
69
- | `setDataMatrix` | method | `(matrix: ExcelValueType[][]) => Promise<void>` | 2차원 배열 데이터를 워크시트에 쓰기 |
70
- | `setRecords` | method | `(records: Record<string, ExcelValueType>[]) => Promise<void>` | 레코드 배열을 워크시트에 쓰기. 첫 행에 헤더 자동 생성 |
71
- | `setZoom` | method | `(percent: number) => Promise<void>` | 워크시트 확대/축소 비율 설정 (퍼센트) |
72
- | `freezeAt` | method | `(point: { r?: number; c?: number }) => Promise<void>` | 행/열 틀 고정 설정 |
73
- | `addImage` | method | `(opts) => Promise<void>` | 워크시트에 이미지 삽입 |
74
-
75
- ## `getDataTable` Options
76
-
77
- | Parameter | Type | Description |
78
- |-----------|------|-------------|
79
- | `opt.headerRowIndex` | `number \| undefined` | 헤더 행 인덱스 (기본값: 데이터 범위의 시작 행) |
80
- | `opt.checkEndColIndex` | `number \| undefined` | 데이터 끝을 판단할 열 인덱스. 이 열이 비어있는 행을 만나면 읽기를 중단한다 |
81
- | `opt.usableHeaderNameFn` | `((headerName: string) => boolean) \| undefined` | 헤더 필터 함수. `false` 반환 시 해당 헤더 제외 |
82
-
83
- ## `addImage` Options
84
-
85
- | Parameter | Type | Description |
86
- |-----------|------|-------------|
87
- | `opts.bytes` | `Bytes` | 이미지 바이너리 데이터 |
88
- | `opts.ext` | `string` | 이미지 확장자 (예: `"png"`, `"jpg"`) |
89
- | `opts.from` | `{ r: number; c: number; rOff?: number \| string; cOff?: number \| string }` | 이미지 시작 위치. `r`/`c`는 0 기반 인덱스, `rOff`/`cOff`는 선택적 EMU 오프셋 |
90
- | `opts.to` | `{ r: number; c: number; rOff?: number \| string; cOff?: number \| string } \| undefined` | 이미지 끝 위치. 생략 시 기본값은 `{ r: from.r + 1, c: from.c + 1 }` |
91
-
92
- ## Usage
93
-
94
- ```typescript
95
- // getDataTable
96
- const table = await ws.getDataTable();
97
- // [{ "이름": "김철수", "나이": 30 }, ...]
98
-
99
- // 특정 행부터 시작하는 경우
100
- const table2 = await ws.getDataTable({ headerRowIndex: 1 });
101
-
102
- // 헤더 필터링
103
- const table3 = await ws.getDataTable({
104
- usableHeaderNameFn: (name) => !name.startsWith("_"),
105
- });
106
-
107
- // 2차원 배열 쓰기
108
- await ws.setDataMatrix([
109
- ["이름", "나이"],
110
- ["김철수", 30],
111
- ]);
112
-
113
- // 레코드 배열 쓰기 (헤더 자동 생성)
114
- await ws.setRecords([
115
- { name: "김철수", age: 30 },
116
- ]);
117
-
118
- // 행 복사 (스타일 포함)
119
- await ws.copyRow(0, 5);
120
-
121
- // 삽입 복사 (기존 행 이동)
122
- await ws.insertCopyRow(0, 3);
123
-
124
- // 틀 고정 (2행부터 고정)
125
- await ws.freezeAt({ r: 1, c: 0 });
126
-
127
- // 이미지 삽입
128
- await ws.addImage({
129
- bytes: imageBytes,
130
- ext: "png",
131
- from: { r: 1, c: 1 },
132
- to: { r: 5, c: 4 },
133
- });
134
- ```
135
-
136
- ## `insertCopyRow` 병합 셀 처리
137
-
138
- - 삽입 지점을 관통하는 다중행 병합은 자동으로 1행 확장됨
139
- - 원본 행의 단일행 병합만 대상 행에 복사됨
@@ -1,33 +0,0 @@
1
- # ExcelAddressPoint
2
-
3
- 셀 좌표를 나타내는 인터페이스이다. 모든 좌표는 0 기반이다.
4
-
5
- ```typescript
6
- export interface ExcelAddressPoint {
7
- r: number;
8
- c: number;
9
- }
10
- ```
11
-
12
- | Field | Type | Description |
13
- |-------|------|-------------|
14
- | `r` | `number` | 행 인덱스 (0 기반) |
15
- | `c` | `number` | 열 인덱스 (0 기반) |
16
-
17
- ## Related Types
18
-
19
- ### `ExcelAddressRangePoint`
20
-
21
- 셀 범위 좌표를 나타내는 인터페이스이다.
22
-
23
- ```typescript
24
- export interface ExcelAddressRangePoint {
25
- s: ExcelAddressPoint;
26
- e: ExcelAddressPoint;
27
- }
28
- ```
29
-
30
- | Field | Type | Description |
31
- |-------|------|-------------|
32
- | `s` | `ExcelAddressPoint` | 시작 좌표 |
33
- | `e` | `ExcelAddressPoint` | 끝 좌표 |
@@ -1,57 +0,0 @@
1
- # ExcelStyleOptions
2
-
3
- 셀 스타일 옵션 인터페이스이다. [`ExcelCell.setStyle()`](../core-classes/excel-cell.md)에서 사용한다.
4
-
5
- ```typescript
6
- export interface ExcelStyleOptions {
7
- background?: string;
8
- border?: ExcelBorderPosition[];
9
- horizontalAlign?: ExcelHorizontalAlign;
10
- verticalAlign?: ExcelVerticalAlign;
11
- numberFormat?: ExcelNumberFormat;
12
- numberFormatCode?: string;
13
- }
14
- ```
15
-
16
- | Field | Type | Description |
17
- |-------|------|-------------|
18
- | `background` | `string \| undefined` | 배경색 (ARGB 형식, 8자리 16진수. 예: `"00FF0000"` = 빨강. alpha는 반전 값) |
19
- | `border` | `ExcelBorderPosition[] \| undefined` | 테두리 위치 배열 |
20
- | `horizontalAlign` | `ExcelHorizontalAlign \| undefined` | 가로 정렬 |
21
- | `verticalAlign` | `ExcelVerticalAlign \| undefined` | 세로 정렬 |
22
- | `numberFormat` | `ExcelNumberFormat \| undefined` | 숫자 형식 프리셋 |
23
- | `numberFormatCode` | `string \| undefined` | 커스텀 Excel formatCode 문자열 (예: `"0.000000"`, `"#,##0.00"`, `"0.00%"`). `numberFormat`과 동시 지정 시 이 필드가 우선 적용된다 |
24
-
25
- ## Related Types
26
-
27
- ### `ExcelNumberFormat`
28
-
29
- 숫자 형식 이름이다. `ExcelStyleOptions.numberFormat`과 [`ExcelUtils`](../utilities/excel-utils.md)의 변환 메서드에서 사용한다.
30
-
31
- ```typescript
32
- export type ExcelNumberFormat = "number" | "string" | "DateOnly" | "DateTime" | "Time";
33
- ```
34
-
35
- ### `ExcelBorderPosition`
36
-
37
- 테두리 위치를 나타내는 타입이다.
38
-
39
- ```typescript
40
- export type ExcelBorderPosition = "left" | "right" | "top" | "bottom";
41
- ```
42
-
43
- ### `ExcelHorizontalAlign`
44
-
45
- 가로 정렬을 나타내는 타입이다.
46
-
47
- ```typescript
48
- export type ExcelHorizontalAlign = "center" | "left" | "right";
49
- ```
50
-
51
- ### `ExcelVerticalAlign`
52
-
53
- 세로 정렬을 나타내는 타입이다.
54
-
55
- ```typescript
56
- export type ExcelVerticalAlign = "center" | "top" | "bottom";
57
- ```
@@ -1,28 +0,0 @@
1
- # ExcelValueType
2
-
3
- 셀에 저장할 수 있는 값의 타입이다.
4
-
5
- ```typescript
6
- export type ExcelValueType = number | string | DateOnly | DateTime | Time | boolean | undefined;
7
- ```
8
-
9
- `DateOnly`, `DateTime`, `Time`은 `@simplysm/core-common` 패키지에서 가져온다.
10
-
11
- ## Related Types
12
-
13
- ### `ExcelCellType`
14
-
15
- Excel 셀 타입이다. XML의 `t` 속성에 대응한다.
16
-
17
- ```typescript
18
- export type ExcelCellType = "s" | "b" | "str" | "n" | "inlineStr" | "e";
19
- ```
20
-
21
- | Value | Description |
22
- |-------|-------------|
23
- | `"s"` | 공유 문자열 (SharedString) |
24
- | `"b"` | boolean |
25
- | `"str"` | 수식 결과 문자열 |
26
- | `"n"` | 숫자 |
27
- | `"inlineStr"` | 인라인 문자열 (서식 있는 텍스트) |
28
- | `"e"` | 에러 |
@@ -1,23 +0,0 @@
1
- # ExcelXmlContentTypeData
2
-
3
- `[Content_Types].xml` 데이터 구조이다. 내부 구현에 사용된다.
4
-
5
- ```typescript
6
- export interface ExcelXmlContentTypeData {
7
- Types: {
8
- $: { xmlns: string };
9
- Default: { $: { Extension: string; ContentType: string } }[];
10
- Override: { $: { PartName: string; ContentType: string } }[];
11
- };
12
- }
13
- ```
14
-
15
- | Field | Type | Description |
16
- |-------|------|-------------|
17
- | `Types.$` | `{ xmlns: string }` | 네임스페이스 |
18
- | `Types.Default` | `Array` | 확장자별 기본 콘텐트 타입 |
19
- | `Types.Default[].$.Extension` | `string` | 파일 확장자 |
20
- | `Types.Default[].$.ContentType` | `string` | MIME 타입 |
21
- | `Types.Override` | `Array` | 파일별 오버라이드 콘텐트 타입 |
22
- | `Types.Override[].$.PartName` | `string` | 파일 경로 |
23
- | `Types.Override[].$.ContentType` | `string` | MIME 타입 |
@@ -1,29 +0,0 @@
1
- # ExcelXmlDrawingData
2
-
3
- `drawing*.xml` 데이터 구조이다. 이미지 앵커 정보를 포함한다. 내부 구현에 사용된다.
4
-
5
- ```typescript
6
- export interface ExcelXmlDrawingData {
7
- wsDr: {
8
- $: { "xmlns": string; "xmlns:a"?: string; "xmlns:r"?: string };
9
- twoCellAnchor?: {
10
- from?: { col: string[]; colOff?: string[]; row: string[]; rowOff?: string[] }[];
11
- to?: { col: string[]; colOff?: string[]; row: string[]; rowOff?: string[] }[];
12
- pic?: {
13
- nvPicPr?: { cNvPr?: { $: { id: string; name: string; descr?: string } }[]; cNvPicPr?: Array<{ "a:picLocks"?: Array<{ $: { noChangeAspect?: string } }> }> }[];
14
- blipFill?: { "a:blip"?: Array<{ $: { "r:embed": string } }>; "a:stretch"?: Array<{ "a:fillRect": unknown[] }> }[];
15
- spPr?: { "a:xfrm"?: Array<{ "a:off"?: Array<{ $: { x: string; y: string } }>; "a:ext"?: Array<{ $: { cx: string; cy: string } }> }>; "a:prstGeom"?: Array<{ "$": { prst: string }; "a:avLst": unknown[] }> }[];
16
- }[];
17
- clientData?: unknown[];
18
- }[];
19
- };
20
- }
21
- ```
22
-
23
- | Field | Type | Description |
24
- |-------|------|-------------|
25
- | `wsDr.$` | `object` | 네임스페이스 |
26
- | `wsDr.twoCellAnchor` | `Array \| undefined` | 두 셀 사이에 앵커된 이미지 목록 |
27
- | `twoCellAnchor.from` | `Array \| undefined` | 시작 위치 (행/열/오프셋) |
28
- | `twoCellAnchor.to` | `Array \| undefined` | 끝 위치 (행/열/오프셋) |
29
- | `twoCellAnchor.pic` | `Array \| undefined` | 이미지 정보 (blip 관계 ID 포함) |
@@ -1,39 +0,0 @@
1
- # ExcelXmlRelationshipData
2
-
3
- `*.rels` 파일 데이터 구조이다. 내부 구현에 사용된다.
4
-
5
- ```typescript
6
- export interface ExcelXmlRelationshipData {
7
- Relationships: {
8
- $: { xmlns: string };
9
- Relationship?: ExcelRelationshipData[];
10
- };
11
- }
12
- ```
13
-
14
- | Field | Type | Description |
15
- |-------|------|-------------|
16
- | `Relationships.$` | `{ xmlns: string }` | 네임스페이스 |
17
- | `Relationships.Relationship` | `ExcelRelationshipData[] \| undefined` | 관계 항목 배열 |
18
-
19
- ## Related Types
20
-
21
- ### `ExcelRelationshipData`
22
-
23
- 개별 Relationship 엔트리 데이터이다.
24
-
25
- ```typescript
26
- export interface ExcelRelationshipData {
27
- $: {
28
- Id: string;
29
- Target: string;
30
- Type: string;
31
- };
32
- }
33
- ```
34
-
35
- | Field | Type | Description |
36
- |-------|------|-------------|
37
- | `$.Id` | `string` | 관계 ID (예: `"rId1"`) |
38
- | `$.Target` | `string` | 대상 파일 경로 |
39
- | `$.Type` | `string` | 관계 타입 URI |
@@ -1,42 +0,0 @@
1
- # ExcelXmlSharedStringData
2
-
3
- `sharedStrings.xml` 데이터 구조이다. 내부 구현에 사용된다.
4
-
5
- ```typescript
6
- export interface ExcelXmlSharedStringData {
7
- sst: {
8
- $: { xmlns: string };
9
- si?: ExcelXmlSharedStringDataSi[];
10
- };
11
- }
12
- ```
13
-
14
- | Field | Type | Description |
15
- |-------|------|-------------|
16
- | `sst.$` | `{ xmlns: string }` | 네임스페이스 |
17
- | `sst.si` | `ExcelXmlSharedStringDataSi[] \| undefined` | 공유 문자열 항목 배열 |
18
-
19
- ## Related Types
20
-
21
- ### `ExcelXmlSharedStringDataSi`
22
-
23
- SharedString 개별 항목이다. discriminated union으로, `t` 키가 있으면 단순 텍스트, `r` 키가 있으면 서식 있는 텍스트(rich text)이다.
24
-
25
- ```typescript
26
- export type ExcelXmlSharedStringDataSi =
27
- | { t: ExcelXmlSharedStringDataText }
28
- | { r: { t: ExcelXmlSharedStringDataText }[] };
29
- ```
30
-
31
- | Variant | Discriminant | Description |
32
- |---------|-------------|-------------|
33
- | `{ t: ... }` | `t` 키 존재 | 단순 텍스트 |
34
- | `{ r: ... }` | `r` 키 존재 | 서식 있는 텍스트 (run 배열) |
35
-
36
- ### `ExcelXmlSharedStringDataText`
37
-
38
- SharedString 텍스트 데이터이다. 단순 문자열 또는 공백 보존 속성이 있는 객체이다.
39
-
40
- ```typescript
41
- export type ExcelXmlSharedStringDataText = [string | { $: { space?: "preserve" }; _?: string }];
42
- ```
@@ -1,97 +0,0 @@
1
- # ExcelXmlStyleData
2
-
3
- `styles.xml` 데이터 구조이다. 내부 구현에 사용된다.
4
-
5
- ```typescript
6
- export interface ExcelXmlStyleData {
7
- styleSheet: {
8
- $: { xmlns: string };
9
- numFmts?: [{ $: { count: string }; numFmt?: { $: { numFmtId: string; formatCode: string } }[] }];
10
- fonts: [{ $: { count: string }; font: {}[] }];
11
- fills: [{ $: { count: string }; fill: ExcelXmlStyleDataFill[] }];
12
- borders: [{ $: { count: string }; border: ExcelXmlStyleDataBorder[] }];
13
- cellXfs: [{ $: { count: string }; xf: ExcelXmlStyleDataXf[] }];
14
- };
15
- }
16
- ```
17
-
18
- | Field | Type | Description |
19
- |-------|------|-------------|
20
- | `styleSheet.numFmts` | `Array \| undefined` | 커스텀 숫자 형식 목록 |
21
- | `styleSheet.fonts` | `Array` | 폰트 목록 |
22
- | `styleSheet.fills` | `Array` | 채우기 스타일 목록 |
23
- | `styleSheet.borders` | `Array` | 테두리 스타일 목록 |
24
- | `styleSheet.cellXfs` | `Array` | 셀 서식(xf) 목록 |
25
-
26
- ## Related Types
27
-
28
- ### `ExcelXmlStyleDataXf`
29
-
30
- 셀 서식(xf) 데이터이다.
31
-
32
- ```typescript
33
- export interface ExcelXmlStyleDataXf {
34
- $: {
35
- numFmtId?: string;
36
- fontId?: string;
37
- fillId?: string;
38
- borderId?: string;
39
- xfId?: string;
40
- applyNumberFormat?: string;
41
- applyFont?: string;
42
- applyAlignment?: string;
43
- applyFill?: string;
44
- applyBorder?: string;
45
- };
46
- alignment?: [{ $: { horizontal?: "center" | "left" | "right"; vertical?: "center" | "top" | "bottom" } }];
47
- }
48
- ```
49
-
50
- | Field | Type | Description |
51
- |-------|------|-------------|
52
- | `$.numFmtId` | `string \| undefined` | 숫자 형식 ID |
53
- | `$.fontId` | `string \| undefined` | 폰트 ID |
54
- | `$.fillId` | `string \| undefined` | 채우기 ID |
55
- | `$.borderId` | `string \| undefined` | 테두리 ID |
56
- | `$.xfId` | `string \| undefined` | 부모 xf ID |
57
- | `$.applyNumberFormat` | `string \| undefined` | 숫자 형식 적용 여부 |
58
- | `$.applyFont` | `string \| undefined` | 폰트 적용 여부 |
59
- | `$.applyAlignment` | `string \| undefined` | 정렬 적용 여부 |
60
- | `$.applyFill` | `string \| undefined` | 채우기 적용 여부 |
61
- | `$.applyBorder` | `string \| undefined` | 테두리 적용 여부 |
62
- | `alignment` | `Array \| undefined` | 정렬 설정 (horizontal, vertical) |
63
-
64
- ### `ExcelXmlStyleDataFill`
65
-
66
- 채우기 스타일 데이터이다.
67
-
68
- ```typescript
69
- export interface ExcelXmlStyleDataFill {
70
- patternFill: [{ $: { patternType: "none" | "solid" | "gray125" }; fgColor?: [{ $: { rgb: string } }] }];
71
- }
72
- ```
73
-
74
- | Field | Type | Description |
75
- |-------|------|-------------|
76
- | `patternFill[0].$.patternType` | `"none" \| "solid" \| "gray125"` | 패턴 유형 |
77
- | `patternFill[0].fgColor` | `[{ $: { rgb: string } }] \| undefined` | 전경색 (ARGB) |
78
-
79
- ### `ExcelXmlStyleDataBorder`
80
-
81
- 테두리 스타일 데이터이다. 각 방향은 선택적이며, `style`과 `color`를 가진다.
82
-
83
- ```typescript
84
- export interface ExcelXmlStyleDataBorder {
85
- top?: [{ $: { style: "thin" | "medium" }; color?: [{ $: { rgb: string } }] }];
86
- left?: [{ $: { style: "thin" | "medium" }; color?: [{ $: { rgb: string } }] }];
87
- right?: [{ $: { style: "thin" | "medium" }; color?: [{ $: { rgb: string } }] }];
88
- bottom?: [{ $: { style: "thin" | "medium" }; color?: [{ $: { rgb: string } }] }];
89
- }
90
- ```
91
-
92
- | Field | Type | Description |
93
- |-------|------|-------------|
94
- | `top` | `Array \| undefined` | 상단 테두리 (`"thin"` 또는 `"medium"`) |
95
- | `left` | `Array \| undefined` | 좌측 테두리 |
96
- | `right` | `Array \| undefined` | 우측 테두리 |
97
- | `bottom` | `Array \| undefined` | 하단 테두리 |
@@ -1,22 +0,0 @@
1
- # ExcelXmlWorkbookData
2
-
3
- `workbook.xml` 데이터 구조이다. 내부 구현에 사용된다.
4
-
5
- ```typescript
6
- export interface ExcelXmlWorkbookData {
7
- workbook: {
8
- $: { "xmlns": string; "xmlns:r"?: string };
9
- bookViews?: [{ workbookView: [{}] }];
10
- sheets?: [{ sheet: { $: { "name": string; "sheetId": string; "r:id": string } }[] }];
11
- };
12
- }
13
- ```
14
-
15
- | Field | Type | Description |
16
- |-------|------|-------------|
17
- | `workbook.$` | `object` | 네임스페이스 |
18
- | `workbook.bookViews` | `Array \| undefined` | 워크북 뷰 설정 |
19
- | `workbook.sheets` | `Array \| undefined` | 시트 목록 |
20
- | `workbook.sheets[0].sheet[].$.name` | `string` | 시트 이름 |
21
- | `workbook.sheets[0].sheet[].$.sheetId` | `string` | 시트 ID |
22
- | `workbook.sheets[0].sheet[].$["r:id"]` | `string` | 관계 ID |
@@ -1,68 +0,0 @@
1
- # ExcelXmlWorksheetData
2
-
3
- `worksheet*.xml` 데이터 구조이다. 내부 구현에 사용된다.
4
-
5
- ```typescript
6
- export interface ExcelXmlWorksheetData {
7
- worksheet: {
8
- $: { "xmlns": string; "xmlns:r"?: string };
9
- dimension?: [{ $: { ref: string } }];
10
- sheetViews?: [{ sheetView: { $: { workbookViewId: string; zoomScale?: string }; pane?: [{ $: { xSplit?: string; ySplit?: string; topLeftCell?: string; activePane?: string; state?: string } }] }[] }];
11
- sheetFormatPr?: [{ $: { defaultRowHeight: string } }];
12
- cols?: [{ col: { $: { min: string; max: string; width?: string; bestFit?: string; customWidth?: string } }[] }];
13
- sheetData: [{ row?: ExcelRowData[] }];
14
- mergeCells?: [{ $: { count: string }; mergeCell: { $: { ref: string } }[] }];
15
- drawing?: { $: { "r:id": string } }[];
16
- };
17
- }
18
- ```
19
-
20
- | Field | Type | Description |
21
- |-------|------|-------------|
22
- | `worksheet.dimension` | `Array \| undefined` | 데이터 범위 (예: `"A1:C10"`) |
23
- | `worksheet.sheetViews` | `Array \| undefined` | 시트 뷰 설정 (줌, 틀 고정) |
24
- | `worksheet.sheetFormatPr` | `Array \| undefined` | 기본 행 높이 |
25
- | `worksheet.cols` | `Array \| undefined` | 열 설정 (너비 등) |
26
- | `worksheet.sheetData` | `Array` | 행 데이터 |
27
- | `worksheet.mergeCells` | `Array \| undefined` | 병합 셀 정보 |
28
- | `worksheet.drawing` | `Array \| undefined` | 드로잉 관계 참조 |
29
-
30
- ## Related Types
31
-
32
- ### `ExcelRowData`
33
-
34
- 행 XML 데이터이다.
35
-
36
- ```typescript
37
- export interface ExcelRowData {
38
- $: { r: string };
39
- c?: ExcelCellData[];
40
- }
41
- ```
42
-
43
- | Field | Type | Description |
44
- |-------|------|-------------|
45
- | `$.r` | `string` | 행 주소 (1 기반, 예: `"1"`, `"10"`) |
46
- | `c` | `ExcelCellData[] \| undefined` | 셀 데이터 배열 |
47
-
48
- ### `ExcelCellData`
49
-
50
- 셀 XML 데이터이다.
51
-
52
- ```typescript
53
- export interface ExcelCellData {
54
- $: { r: string; s?: string; t?: ExcelCellType };
55
- v?: [string];
56
- f?: [string];
57
- is?: { t?: (string | { _?: string })[] }[];
58
- }
59
- ```
60
-
61
- | Field | Type | Description |
62
- |-------|------|-------------|
63
- | `$.r` | `string` | 셀 주소 (예: `"A1"`, `"B3"`) |
64
- | `$.s` | `string \| undefined` | 스타일 ID |
65
- | `$.t` | `ExcelCellType \| undefined` | 셀 타입 |
66
- | `v` | `[string] \| undefined` | 셀 값 |
67
- | `f` | `[string] \| undefined` | 수식 |
68
- | `is` | `Array \| undefined` | 인라인 문자열 데이터 |
@@ -1,15 +0,0 @@
1
- # ExcelXml
2
-
3
- XML 처리 클래스가 구현하는 인터페이스이다. `xml/` 디렉터리의 내부 클래스들이 이를 구현한다. 외부에서 직접 사용하지 않는다.
4
-
5
- ```typescript
6
- export interface ExcelXml {
7
- readonly data: unknown;
8
- cleanup(): void;
9
- }
10
- ```
11
-
12
- | Field | Type | Description |
13
- |-------|------|-------------|
14
- | `data` | `unknown` | XML 파싱된 데이터 (read-only) |
15
- | `cleanup` | `() => void` | `ZipCache.toBytes()` 직전에 호출되어 직렬화 전 데이터를 정리한다 |
@@ -1,93 +0,0 @@
1
- # ExcelUtils
2
-
3
- Excel 유틸리티 함수 모음. 셀 주소 변환, 날짜/숫자 변환, 숫자 형식 처리 정적 메서드를 제공한다.
4
-
5
- ```typescript
6
- export class ExcelUtils {
7
- // 주소 변환
8
- static stringifyAddr(point: ExcelAddressPoint): string;
9
- static stringifyRowAddr(r: number): string;
10
- static stringifyColAddr(c: number): string;
11
- static parseRowAddr(addr: string): number;
12
- static parseColAddr(addr: string): number;
13
- static parseCellAddr(addr: string): ExcelAddressPoint;
14
- static parseRangeAddr(rangeAddr: string): ExcelAddressRangePoint;
15
- static stringifyRangeAddr(point: ExcelAddressRangePoint): string;
16
-
17
- // 날짜/숫자 변환
18
- static convertTimeTickToNumber(tick: number): number;
19
- static convertNumberToTimeTick(value: number): number;
20
-
21
- // 숫자 형식 처리
22
- static convertNumFmtCodeToName(numFmtCode: string): ExcelNumberFormat;
23
- static convertNumFmtIdToName(numFmtId: number): ExcelNumberFormat;
24
- static convertNumFmtNameToId(numFmtName: ExcelNumberFormat): number;
25
- }
26
- ```
27
-
28
- ## Members
29
-
30
- | Member | Kind | Type | Description |
31
- |--------|------|------|-------------|
32
- | `stringifyAddr` | static | `(point: ExcelAddressPoint) => string` | 셀 좌표를 "A1" 형식 문자열로 변환 |
33
- | `stringifyRowAddr` | static | `(r: number) => string` | 행 인덱스(0 기반)를 행 주소 문자열로 변환 |
34
- | `stringifyColAddr` | static | `(c: number) => string` | 열 인덱스(0 기반)를 열 주소 문자열로 변환. 범위: 0~16383 |
35
- | `parseRowAddr` | static | `(addr: string) => number` | 셀 주소에서 0 기반 행 인덱스 추출 |
36
- | `parseColAddr` | static | `(addr: string) => number` | 셀 주소에서 0 기반 열 인덱스 추출 |
37
- | `parseCellAddr` | static | `(addr: string) => ExcelAddressPoint` | 셀 주소를 좌표로 변환 |
38
- | `parseRangeAddr` | static | `(rangeAddr: string) => ExcelAddressRangePoint` | 범위 주소를 좌표로 변환 |
39
- | `stringifyRangeAddr` | static | `(point: ExcelAddressRangePoint) => string` | 범위 좌표를 주소 문자열로 변환. 시작=끝이면 단일 셀 주소 반환 |
40
- | `convertTimeTickToNumber` | static | `(tick: number) => number` | JavaScript 타임스탬프(ms)를 Excel 날짜 숫자로 변환 |
41
- | `convertNumberToTimeTick` | static | `(value: number) => number` | Excel 날짜 숫자를 JavaScript 타임스탬프(ms)로 변환 |
42
- | `convertNumFmtCodeToName` | static | `(numFmtCode: string) => ExcelNumberFormat` | 숫자 형식 코드를 형식 이름으로 변환 |
43
- | `convertNumFmtIdToName` | static | `(numFmtId: number) => ExcelNumberFormat` | Excel 내장 숫자 형식 ID를 형식 이름으로 변환 |
44
- | `convertNumFmtNameToId` | static | `(numFmtName: ExcelNumberFormat) => number` | 숫자 형식 이름을 형식 ID로 변환 |
45
-
46
- ## Usage
47
-
48
- ```typescript
49
- import { ExcelUtils } from "@simplysm/excel";
50
-
51
- // 주소 변환
52
- ExcelUtils.stringifyAddr({ r: 0, c: 0 }); // "A1"
53
- ExcelUtils.stringifyAddr({ r: 2, c: 3 }); // "D3"
54
- ExcelUtils.parseCellAddr("B3"); // { r: 2, c: 1 }
55
- ExcelUtils.parseRangeAddr("A1:C3"); // { s: { r: 0, c: 0 }, e: { r: 2, c: 2 } }
56
- ExcelUtils.stringifyRangeAddr({ s: { r: 0, c: 0 }, e: { r: 2, c: 2 } }); // "A1:C3"
57
-
58
- ExcelUtils.stringifyRowAddr(0); // "1"
59
- ExcelUtils.stringifyColAddr(0); // "A"
60
- ExcelUtils.stringifyColAddr(26); // "AA"
61
- ExcelUtils.parseRowAddr("A3"); // 2
62
- ExcelUtils.parseColAddr("B3"); // 1
63
- ```
64
-
65
- ## `convertNumFmtCodeToName` 변환 규칙
66
-
67
- | 형식 코드 패턴 | 반환값 |
68
- |----------------|--------|
69
- | `"General"` | `"number"` |
70
- | `yy`, `dd`, `mm`(날짜 문맥) 포함 + 시간(`h`, `ss`) 포함 | `"DateTime"` |
71
- | `yy`, `dd`, `mm`(날짜 문맥) 포함 | `"DateOnly"` |
72
- | `h`, `ss` 포함 | `"Time"` |
73
- | 숫자 패턴 (`0`, `#`, `.` 등) | `"number"` |
74
-
75
- ## `convertNumFmtIdToName` 내장 형식 ID 범위
76
-
77
- | ID 범위 | 형식 |
78
- |---------|------|
79
- | 0~13, 37~40, 48 | `"number"` (숫자/일반/통화/퍼센트) |
80
- | 14~17, 27~31, 34~36, 50~58 | `"DateOnly"` (날짜, 로컬라이즈 포함) |
81
- | 22 | `"DateTime"` (날짜+시간) |
82
- | 18~21, 32~33, 45~47 | `"Time"` (시간) |
83
- | 49 | `"string"` (텍스트) |
84
-
85
- ## `convertNumFmtNameToId` 매핑
86
-
87
- | 형식 이름 | ID |
88
- |-----------|-----|
89
- | `"number"` | 0 |
90
- | `"DateOnly"` | 14 |
91
- | `"DateTime"` | 22 |
92
- | `"Time"` | 18 |
93
- | `"string"` | 49 |
@@ -1,100 +0,0 @@
1
- # ExcelWrapper
2
-
3
- Zod 스키마 기반 타입 안전한 Excel 읽기/쓰기 래퍼. 스키마에서 타입 정보를 추론하여 타입 안전한 읽기/쓰기를 제공한다.
4
-
5
- ```typescript
6
- export class ExcelWrapper<TSchema extends z.ZodObject<z.ZodRawShape>> {
7
- constructor(schema: TSchema);
8
-
9
- async read(
10
- file: Bytes | Blob,
11
- wsNameOrIndex?: string | number,
12
- options?: { excludes?: (keyof z.infer<TSchema>)[] },
13
- ): Promise<z.infer<TSchema>[]>;
14
-
15
- async write(
16
- wsName: string,
17
- records: Partial<z.infer<TSchema>>[],
18
- options?: { excludes?: (keyof z.infer<TSchema>)[] },
19
- ): Promise<ExcelWorkbook>;
20
- }
21
- ```
22
-
23
- ## Members
24
-
25
- | Member | Kind | Type | Description |
26
- |--------|------|------|-------------|
27
- | `constructor` | method | `(schema: TSchema) => ExcelWrapper<TSchema>` | Zod 스키마를 받아 인스턴스 생성. `.describe()`로 Excel 헤더 이름을 지정한다 |
28
- | `read` | method | `(file, wsNameOrIndex?, options?) => Promise<z.infer<TSchema>[]>` | Excel 파일을 레코드 배열로 읽기. 스키마 유효성 검사 수행 |
29
- | `write` | method | `(wsName, records, options?) => Promise<ExcelWorkbook>` | 레코드 배열을 Excel 워크북으로 변환. 반환된 워크북의 `close()`는 호출자 책임 |
30
-
31
- ## Parameters
32
-
33
- ### `read(file, wsNameOrIndex?, options?)`
34
-
35
- | Parameter | Type | Description |
36
- |-----------|------|-------------|
37
- | `file` | `Bytes \| Blob` | Excel 파일 데이터 |
38
- | `wsNameOrIndex` | `string \| number` | 워크시트 이름 또는 0 기반 인덱스 (기본값: `0`) |
39
- | `options.excludes` | `(keyof z.infer<TSchema>)[] \| undefined` | 읽기에서 제외할 필드 키 배열 |
40
-
41
- **타입 변환 규칙:**
42
-
43
- | 스키마 타입 | 변환 동작 |
44
- |------------|-----------|
45
- | `z.string()` | 문자열로 변환 (`String(rawValue)`) |
46
- | `z.number()` | 숫자로 파싱 (`num.parseFloat`) |
47
- | `z.boolean()` | `"1"`, `"true"` → `true`, `"0"`, `"false"` → `false` |
48
- | `z.optional()` / `z.nullable()` | 빈 셀을 `undefined`로 반환 |
49
- | `z.default(value)` | 빈 셀에 기본값 적용 |
50
- | `DateOnly` / `DateTime` / `Time` | `instanceof`로 직접 전달 |
51
-
52
- ### `write(wsName, records, options?)`
53
-
54
- | Parameter | Type | Description |
55
- |-----------|------|-------------|
56
- | `wsName` | `string` | 워크시트 이름 |
57
- | `records` | `Partial<z.infer<TSchema>>[]` | 레코드 배열 |
58
- | `options.excludes` | `(keyof z.infer<TSchema>)[] \| undefined` | 쓰기에서 제외할 필드 키 배열 |
59
-
60
- **쓰기 동작:**
61
-
62
- - 첫 번째 행에 헤더 자동 생성 (스키마의 `.describe()` 값 사용)
63
- - 모든 셀에 테두리 스타일 자동 적용
64
- - 필수 비boolean 필드의 헤더에 노란색 배경(`00FFFF00`) 강조
65
- - 확대/축소 85%, 첫 번째 행 틀 고정 자동 설정
66
- - 내부에서 에러 발생 시 워크북이 자동으로 `close()`됨
67
-
68
- ## Usage
69
-
70
- ```typescript
71
- import { ExcelWrapper } from "@simplysm/excel";
72
- import { z } from "zod";
73
-
74
- const schema = z.object({
75
- name: z.string().describe("이름"),
76
- age: z.number().describe("나이"),
77
- email: z.string().optional().describe("이메일"),
78
- active: z.boolean().default(false).describe("활성"),
79
- });
80
-
81
- const wrapper = new ExcelWrapper(schema);
82
-
83
- // 쓰기 (시트명, 레코드 배열)
84
- const wb = await wrapper.write("사람", [
85
- { name: "김철수", age: 30, email: "kim@example.com" },
86
- { name: "이영희", age: 28 },
87
- ]);
88
- try {
89
- const bytes = await wb.toBytes();
90
- } finally {
91
- await wb.close();
92
- }
93
-
94
- // 읽기 (시트명 또는 인덱스, 기본값: 0)
95
- const records = await wrapper.read(bytes, "사람");
96
- // z.infer<typeof schema>[] 타입으로 반환
97
-
98
- // excludes 옵션으로 특정 필드 제외
99
- const filtered = await wrapper.read(bytes, 0, { excludes: ["email"] });
100
- ```