@simplysm/excel 14.0.47 → 14.0.49
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/README.md +149 -0
- package/dist/xml/excel-xml-workbook.js +2 -2
- package/dist/xml/excel-xml-workbook.js.map +1 -1
- package/docs/core-classes.md +453 -0
- package/docs/types.md +459 -0
- package/docs/utilities.md +194 -0
- package/docs/wrapper.md +73 -0
- package/package.json +4 -3
- package/src/xml/excel-xml-workbook.ts +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
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
|
+
| API | Type | Description |
|
|
16
|
+
|-----|------|-------------|
|
|
17
|
+
| `ExcelWorkbook` | class | Excel 워크북 진입점. 워크시트 생성/조회, 바이트 내보내기, ZIP 리소스 관리 |
|
|
18
|
+
| `ExcelWorksheet` | class | 워크시트. 셀/행/열 접근, 행/셀 복사, 데이터 테이블 읽기, 이미지 삽입, 시트명 변경 |
|
|
19
|
+
| `ExcelCell` | class | 개별 셀. 값/수식 읽기/쓰기, 스타일 설정, 셀 병합 |
|
|
20
|
+
| `ExcelRow` | class | 워크시트 행. 셀 접근, 행 전체 셀 조회 |
|
|
21
|
+
| `ExcelCol` | class | 워크시트 열. 셀 접근, 열 너비 설정 |
|
|
22
|
+
|
|
23
|
+
→ See [docs/core-classes.md](./docs/core-classes.md) for details.
|
|
24
|
+
|
|
25
|
+
### Wrapper
|
|
26
|
+
|
|
27
|
+
| API | Type | Description |
|
|
28
|
+
|-----|------|-------------|
|
|
29
|
+
| `ExcelWrapper` | class | Zod 스키마 기반 타입 안전한 Excel 읽기/쓰기. 헤더 자동 생성, 유효성 검사, 필수 필드 강조 |
|
|
30
|
+
|
|
31
|
+
→ See [docs/wrapper.md](./docs/wrapper.md) for details.
|
|
32
|
+
|
|
33
|
+
### Utilities
|
|
34
|
+
|
|
35
|
+
| API | Type | Description |
|
|
36
|
+
|-----|------|-------------|
|
|
37
|
+
| `ExcelUtils` | class | 셀 주소 변환 (좌표↔문자열), 날짜↔숫자 변환, 숫자 형식 매핑 (정적 메서드) |
|
|
38
|
+
|
|
39
|
+
→ See [docs/utilities.md](./docs/utilities.md) for details.
|
|
40
|
+
|
|
41
|
+
### Types
|
|
42
|
+
|
|
43
|
+
| API | Type | Description |
|
|
44
|
+
|-----|------|-------------|
|
|
45
|
+
| `ExcelValueType` | type | 셀 값 타입: number, string, DateOnly, DateTime, Time, boolean, undefined |
|
|
46
|
+
| `ExcelNumberFormat` | type | 숫자 형식 이름: "number", "string", "DateOnly", "DateTime", "Time" |
|
|
47
|
+
| `ExcelCellType` | type | 셀 타입: "s"(공유문자열), "b"(boolean), "str"(수식문자열), "n"(숫자), "inlineStr", "e"(에러) |
|
|
48
|
+
| `ExcelAddressPoint` | interface | 셀 좌표 (0 기반 r, c) |
|
|
49
|
+
| `ExcelAddressRangePoint` | interface | 셀 범위 좌표 (시작점 s, 끝점 e) |
|
|
50
|
+
| `ExcelStyleOptions` | interface | 셀 스타일 옵션 (배경색, 테두리, 정렬, 숫자 형식) |
|
|
51
|
+
| `ExcelBorderPosition` | type | 테두리 위치: "left", "right", "top", "bottom" |
|
|
52
|
+
| `ExcelHorizontalAlign` | type | 가로 정렬: "left", "center", "right" |
|
|
53
|
+
| `ExcelVerticalAlign` | type | 세로 정렬: "top", "center", "bottom" |
|
|
54
|
+
| `ExcelXml` | interface | XML 처리 클래스가 구현하는 인터페이스 (내부용) |
|
|
55
|
+
| `ExcelXmlContentTypeData` | interface | `[Content_Types].xml` 데이터 구조 (내부용) |
|
|
56
|
+
| `ExcelXmlRelationshipData` | interface | `*.rels` 파일 데이터 구조 (내부용) |
|
|
57
|
+
| `ExcelRelationshipData` | interface | 개별 Relationship 엔트리 데이터 (내부용) |
|
|
58
|
+
| `ExcelXmlWorkbookData` | interface | `workbook.xml` 데이터 구조 (내부용) |
|
|
59
|
+
| `ExcelXmlWorksheetData` | interface | `worksheet*.xml` 데이터 구조 (내부용) |
|
|
60
|
+
| `ExcelRowData` | interface | 행 XML 데이터 (내부용) |
|
|
61
|
+
| `ExcelCellData` | interface | 셀 XML 데이터 (내부용) |
|
|
62
|
+
| `ExcelXmlDrawingData` | interface | `drawing*.xml` 데이터 구조 (내부용) |
|
|
63
|
+
| `ExcelXmlSharedStringData` | interface | `sharedStrings.xml` 데이터 구조 (내부용) |
|
|
64
|
+
| `ExcelXmlSharedStringDataSi` | type | SharedString 개별 항목 (단순 텍스트 or rich text) |
|
|
65
|
+
| `ExcelXmlSharedStringDataText` | type | SharedString 텍스트 데이터 (내부용) |
|
|
66
|
+
| `ExcelXmlStyleData` | interface | `styles.xml` 데이터 구조 (내부용) |
|
|
67
|
+
| `ExcelXmlStyleDataXf` | interface | 셀 서식(xf) 데이터 (내부용) |
|
|
68
|
+
| `ExcelXmlStyleDataFill` | interface | 채우기 스타일 데이터 (내부용) |
|
|
69
|
+
| `ExcelXmlStyleDataBorder` | interface | 테두리 스타일 데이터 (내부용) |
|
|
70
|
+
|
|
71
|
+
→ See [docs/types.md](./docs/types.md) for details.
|
|
72
|
+
|
|
73
|
+
## Usage Examples
|
|
74
|
+
|
|
75
|
+
### 새 Excel 파일 생성 및 저장
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { ExcelWorkbook } from "@simplysm/excel";
|
|
79
|
+
|
|
80
|
+
const wb = new ExcelWorkbook();
|
|
81
|
+
try {
|
|
82
|
+
const ws = await wb.addWorksheet("Sheet1");
|
|
83
|
+
|
|
84
|
+
// 헤더 행
|
|
85
|
+
await ws.cell(0, 0).setValue("이름");
|
|
86
|
+
await ws.cell(0, 1).setValue("나이");
|
|
87
|
+
|
|
88
|
+
// 데이터 행
|
|
89
|
+
await ws.cell(1, 0).setValue("김철수");
|
|
90
|
+
await ws.cell(1, 1).setValue(30);
|
|
91
|
+
|
|
92
|
+
const bytes = await wb.toBytes();
|
|
93
|
+
// 파일 저장 또는 전송
|
|
94
|
+
} finally {
|
|
95
|
+
await wb.close();
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 기존 Excel 파일 읽기
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
import { ExcelWorkbook } from "@simplysm/excel";
|
|
103
|
+
|
|
104
|
+
const bytes = /* 파일 바이트 배열 */;
|
|
105
|
+
const wb = new ExcelWorkbook(bytes);
|
|
106
|
+
try {
|
|
107
|
+
// 시트명 또는 인덱스(0 기반)로 조회
|
|
108
|
+
const ws = await wb.getWorksheet(0);
|
|
109
|
+
|
|
110
|
+
// 개별 셀 읽기
|
|
111
|
+
const value = await ws.cell(0, 0).getValue();
|
|
112
|
+
|
|
113
|
+
// 전체 데이터 테이블 읽기 (첫 행이 헤더)
|
|
114
|
+
const table = await ws.getDataTable();
|
|
115
|
+
} finally {
|
|
116
|
+
await wb.close();
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Zod 스키마 기반 타입 안전한 작업
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
import { ExcelWrapper } from "@simplysm/excel";
|
|
124
|
+
import { z } from "zod";
|
|
125
|
+
|
|
126
|
+
const schema = z.object({
|
|
127
|
+
name: z.string().describe("이름"),
|
|
128
|
+
age: z.number().describe("나이"),
|
|
129
|
+
email: z.string().optional().describe("이메일"),
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
const wrapper = new ExcelWrapper(schema);
|
|
133
|
+
|
|
134
|
+
// 레코드 배열을 Excel로 쓰기
|
|
135
|
+
const records = [
|
|
136
|
+
{ name: "김철수", age: 30, email: "kim@example.com" },
|
|
137
|
+
{ name: "이영희", age: 28 },
|
|
138
|
+
];
|
|
139
|
+
const wb = await wrapper.write("사람", records);
|
|
140
|
+
try {
|
|
141
|
+
const bytes = await wb.toBytes();
|
|
142
|
+
} finally {
|
|
143
|
+
await wb.close();
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Excel 파일을 레코드 배열로 읽기 (유효성 검사 포함)
|
|
147
|
+
const bytes = /* 파일 바이트 배열 */;
|
|
148
|
+
const data = await wrapper.read(bytes, "사람");
|
|
149
|
+
```
|
|
@@ -96,8 +96,8 @@ export class ExcelXmlWorkbook {
|
|
|
96
96
|
return (this.data.workbook.sheets?.[0].sheet ?? []).single((item) => num.parseInt(item.$["r:id"]) === id);
|
|
97
97
|
}
|
|
98
98
|
_getReplacedName(name) {
|
|
99
|
-
//-- 잘못된 시트 이름
|
|
100
|
-
return name.replace(/[:\\/?*\[\]']/g, "
|
|
99
|
+
//-- 잘못된 시트 이름 문자 제거. 전부 제거되어 빈 문자열이 되면 "Sheet" 사용.
|
|
100
|
+
return name.replace(/[:\\/?*\[\]']/g, "") || "Sheet";
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
//# sourceMappingURL=excel-xml-workbook.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"excel-xml-workbook.js","sourceRoot":"","sources":["../../src/xml/excel-xml-workbook.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"excel-xml-workbook.js","sourceRoot":"","sources":["../../src/xml/excel-xml-workbook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
# Core Classes
|
|
2
|
+
|
|
3
|
+
## `ExcelWorkbook`
|
|
4
|
+
|
|
5
|
+
Excel 워크북 처리 클래스. 내부적으로 ZIP 리소스를 관리하므로 사용 후 반드시 `try-finally` 블록에서 `close()`를 호출해야 한다.
|
|
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
|
+
### Constructor
|
|
23
|
+
|
|
24
|
+
| Parameter | Type | Description |
|
|
25
|
+
|-----------|------|-------------|
|
|
26
|
+
| `arg` | `Blob \| Bytes \| undefined` | 기존 Excel 파일 데이터. 생략하면 새 워크북을 생성한다 |
|
|
27
|
+
|
|
28
|
+
### Methods
|
|
29
|
+
|
|
30
|
+
#### `getWorksheetNames()`
|
|
31
|
+
|
|
32
|
+
워크북의 모든 워크시트 이름을 배열로 반환한다.
|
|
33
|
+
|
|
34
|
+
#### `addWorksheet(name)`
|
|
35
|
+
|
|
36
|
+
새 워크시트를 생성하여 `ExcelWorksheet` 인스턴스를 반환한다.
|
|
37
|
+
|
|
38
|
+
| Parameter | Type | Description |
|
|
39
|
+
|-----------|------|-------------|
|
|
40
|
+
| `name` | `string` | 워크시트 이름 |
|
|
41
|
+
|
|
42
|
+
#### `getWorksheet(nameOrIndex)`
|
|
43
|
+
|
|
44
|
+
이름 또는 0 기반 인덱스로 워크시트를 조회하여 반환한다. 찾을 수 없으면 에러를 던진다.
|
|
45
|
+
|
|
46
|
+
| Parameter | Type | Description |
|
|
47
|
+
|-----------|------|-------------|
|
|
48
|
+
| `nameOrIndex` | `string \| number` | 워크시트 이름 또는 0 기반 인덱스 |
|
|
49
|
+
|
|
50
|
+
#### `toBytes()`
|
|
51
|
+
|
|
52
|
+
워크북을 `Bytes`(Uint8Array)로 내보낸다.
|
|
53
|
+
|
|
54
|
+
#### `toBlob()`
|
|
55
|
+
|
|
56
|
+
워크북을 `Blob`으로 내보낸다. MIME 타입은 `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`이다.
|
|
57
|
+
|
|
58
|
+
#### `close()`
|
|
59
|
+
|
|
60
|
+
ZIP 리더와 내부 캐시를 정리한다. 이미 닫힌 워크북에 대해 호출해도 안전하다 (no-op). 닫힌 워크북의 메서드를 호출하면 에러가 발생한다.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## `ExcelWorksheet`
|
|
65
|
+
|
|
66
|
+
Excel 워크시트를 나타내는 클래스. 셀 접근, 행/열 복사, 데이터 테이블 처리, 이미지 삽입, 뷰 설정 기능을 제공한다.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
export class ExcelWorksheet {
|
|
70
|
+
constructor(zipCache: ZipCache, relId: number, targetFileName: string);
|
|
71
|
+
|
|
72
|
+
// Name
|
|
73
|
+
async getName(): Promise<string>;
|
|
74
|
+
async setName(newName: string): Promise<void>;
|
|
75
|
+
|
|
76
|
+
// Cell Access (0 기반)
|
|
77
|
+
row(r: number): ExcelRow;
|
|
78
|
+
cell(r: number, c: number): ExcelCell;
|
|
79
|
+
col(c: number): ExcelCol;
|
|
80
|
+
|
|
81
|
+
// Copy
|
|
82
|
+
async copyRowStyle(srcR: number, targetR: number): Promise<void>;
|
|
83
|
+
async copyCellStyle(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint): Promise<void>;
|
|
84
|
+
async copyRow(srcR: number, targetR: number): Promise<void>;
|
|
85
|
+
async copyCell(srcAddr: ExcelAddressPoint, targetAddr: ExcelAddressPoint): Promise<void>;
|
|
86
|
+
async insertCopyRow(srcR: number, targetR: number): Promise<void>;
|
|
87
|
+
|
|
88
|
+
// Range
|
|
89
|
+
async getRange(): Promise<ExcelAddressRangePoint>;
|
|
90
|
+
async getCells(): Promise<ExcelCell[][]>;
|
|
91
|
+
|
|
92
|
+
// Data
|
|
93
|
+
async getDataTable(opt?: {
|
|
94
|
+
headerRowIndex?: number;
|
|
95
|
+
checkEndColIndex?: number;
|
|
96
|
+
usableHeaderNameFn?: (headerName: string) => boolean;
|
|
97
|
+
}): Promise<Record<string, ExcelValueType>[]>;
|
|
98
|
+
async setDataMatrix(matrix: ExcelValueType[][]): Promise<void>;
|
|
99
|
+
async setRecords(records: Record<string, ExcelValueType>[]): Promise<void>;
|
|
100
|
+
|
|
101
|
+
// View
|
|
102
|
+
async setZoom(percent: number): Promise<void>;
|
|
103
|
+
async freezeAt(point: { r?: number; c?: number }): Promise<void>;
|
|
104
|
+
|
|
105
|
+
// Image
|
|
106
|
+
async addImage(opts: {
|
|
107
|
+
bytes: Bytes;
|
|
108
|
+
ext: string;
|
|
109
|
+
from: { r: number; c: number; rOff?: number | string; cOff?: number | string };
|
|
110
|
+
to?: { r: number; c: number; rOff?: number | string; cOff?: number | string };
|
|
111
|
+
}): Promise<void>;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Name Methods
|
|
116
|
+
|
|
117
|
+
#### `getName()`
|
|
118
|
+
|
|
119
|
+
워크시트 이름을 반환한다.
|
|
120
|
+
|
|
121
|
+
#### `setName(newName)`
|
|
122
|
+
|
|
123
|
+
워크시트 이름을 변경한다.
|
|
124
|
+
|
|
125
|
+
| Parameter | Type | Description |
|
|
126
|
+
|-----------|------|-------------|
|
|
127
|
+
| `newName` | `string` | 새 워크시트 이름 |
|
|
128
|
+
|
|
129
|
+
### Cell Access Methods
|
|
130
|
+
|
|
131
|
+
모든 좌표는 0 기반 인덱스이다.
|
|
132
|
+
|
|
133
|
+
#### `row(r)`
|
|
134
|
+
|
|
135
|
+
행 객체를 반환한다.
|
|
136
|
+
|
|
137
|
+
| Parameter | Type | Description |
|
|
138
|
+
|-----------|------|-------------|
|
|
139
|
+
| `r` | `number` | 행 인덱스 (0 기반) |
|
|
140
|
+
|
|
141
|
+
#### `cell(r, c)`
|
|
142
|
+
|
|
143
|
+
셀 객체를 반환한다. 동일 좌표에 대해 항상 동일한 `ExcelCell` 인스턴스를 반환한다.
|
|
144
|
+
|
|
145
|
+
| Parameter | Type | Description |
|
|
146
|
+
|-----------|------|-------------|
|
|
147
|
+
| `r` | `number` | 행 인덱스 (0 기반) |
|
|
148
|
+
| `c` | `number` | 열 인덱스 (0 기반) |
|
|
149
|
+
|
|
150
|
+
#### `col(c)`
|
|
151
|
+
|
|
152
|
+
열 객체를 반환한다.
|
|
153
|
+
|
|
154
|
+
| Parameter | Type | Description |
|
|
155
|
+
|-----------|------|-------------|
|
|
156
|
+
| `c` | `number` | 열 인덱스 (0 기반) |
|
|
157
|
+
|
|
158
|
+
### Copy Methods
|
|
159
|
+
|
|
160
|
+
#### `copyRowStyle(srcR, targetR)`
|
|
161
|
+
|
|
162
|
+
원본 행의 스타일을 대상 행으로 복사한다. 데이터 범위 내의 모든 열에 대해 셀 스타일을 복사한다.
|
|
163
|
+
|
|
164
|
+
| Parameter | Type | Description |
|
|
165
|
+
|-----------|------|-------------|
|
|
166
|
+
| `srcR` | `number` | 원본 행 인덱스 (0 기반) |
|
|
167
|
+
| `targetR` | `number` | 대상 행 인덱스 (0 기반) |
|
|
168
|
+
|
|
169
|
+
#### `copyCellStyle(srcAddr, targetAddr)`
|
|
170
|
+
|
|
171
|
+
원본 셀의 스타일을 대상 셀로 복사한다.
|
|
172
|
+
|
|
173
|
+
| Parameter | Type | Description |
|
|
174
|
+
|-----------|------|-------------|
|
|
175
|
+
| `srcAddr` | `ExcelAddressPoint` | 원본 셀 좌표 |
|
|
176
|
+
| `targetAddr` | `ExcelAddressPoint` | 대상 셀 좌표 |
|
|
177
|
+
|
|
178
|
+
#### `copyRow(srcR, targetR)`
|
|
179
|
+
|
|
180
|
+
원본 행을 대상 행으로 복사한다 (덮어쓰기).
|
|
181
|
+
|
|
182
|
+
| Parameter | Type | Description |
|
|
183
|
+
|-----------|------|-------------|
|
|
184
|
+
| `srcR` | `number` | 원본 행 인덱스 (0 기반) |
|
|
185
|
+
| `targetR` | `number` | 대상 행 인덱스 (0 기반) |
|
|
186
|
+
|
|
187
|
+
#### `copyCell(srcAddr, targetAddr)`
|
|
188
|
+
|
|
189
|
+
원본 셀을 대상 셀로 복사한다.
|
|
190
|
+
|
|
191
|
+
| Parameter | Type | Description |
|
|
192
|
+
|-----------|------|-------------|
|
|
193
|
+
| `srcAddr` | `ExcelAddressPoint` | 원본 셀 좌표 |
|
|
194
|
+
| `targetAddr` | `ExcelAddressPoint` | 대상 셀 좌표 |
|
|
195
|
+
|
|
196
|
+
#### `insertCopyRow(srcR, targetR)`
|
|
197
|
+
|
|
198
|
+
원본 행을 대상 위치에 삽입 복사한다. 대상 위치 이하의 기존 행은 한 칸 아래로 밀린다. 병합 셀도 자동으로 이동/확장된다.
|
|
199
|
+
|
|
200
|
+
| Parameter | Type | Description |
|
|
201
|
+
|-----------|------|-------------|
|
|
202
|
+
| `srcR` | `number` | 복사할 원본 행 인덱스 (0 기반) |
|
|
203
|
+
| `targetR` | `number` | 삽입할 대상 행 인덱스 (0 기반) |
|
|
204
|
+
|
|
205
|
+
**병합 셀 처리:**
|
|
206
|
+
- 삽입 지점을 관통하는 다중행 병합은 자동으로 1행 확장됨
|
|
207
|
+
- 원본 행의 단일행 병합만 대상 행에 복사됨
|
|
208
|
+
|
|
209
|
+
### Range Methods
|
|
210
|
+
|
|
211
|
+
#### `getRange()`
|
|
212
|
+
|
|
213
|
+
워크시트의 데이터 범위를 `ExcelAddressRangePoint`로 반환한다.
|
|
214
|
+
|
|
215
|
+
#### `getCells()`
|
|
216
|
+
|
|
217
|
+
모든 셀을 2차원 배열(`ExcelCell[][]`)로 반환한다.
|
|
218
|
+
|
|
219
|
+
### Data Methods
|
|
220
|
+
|
|
221
|
+
#### `getDataTable(opt?)`
|
|
222
|
+
|
|
223
|
+
워크시트 데이터를 테이블(레코드 배열)로 반환한다. 지정된 헤더 행(기본값: 첫 번째 행)을 기준으로 이하의 데이터를 읽는다.
|
|
224
|
+
|
|
225
|
+
| Parameter | Type | Description |
|
|
226
|
+
|-----------|------|-------------|
|
|
227
|
+
| `opt.headerRowIndex` | `number \| undefined` | 헤더 행 인덱스 (기본값: 데이터 범위의 시작 행) |
|
|
228
|
+
| `opt.checkEndColIndex` | `number \| undefined` | 데이터 끝을 판단할 열 인덱스. 이 열이 비어있는 행을 만나면 데이터가 끝난 것으로 판단한다 |
|
|
229
|
+
| `opt.usableHeaderNameFn` | `(headerName: string) => boolean \| undefined` | 사용 가능한 헤더를 필터링하는 함수. 반환값이 `false`인 헤더는 제외된다 |
|
|
230
|
+
|
|
231
|
+
**반환값:** `Record<string, ExcelValueType>[]` - 헤더를 키로 하는 레코드 배열
|
|
232
|
+
|
|
233
|
+
#### `setDataMatrix(matrix)`
|
|
234
|
+
|
|
235
|
+
2차원 배열 데이터를 워크시트에 쓴다. (0, 0) 위치부터 시작하여 데이터를 기록한다.
|
|
236
|
+
|
|
237
|
+
| Parameter | Type | Description |
|
|
238
|
+
|-----------|------|-------------|
|
|
239
|
+
| `matrix` | `ExcelValueType[][]` | 2차원 배열 데이터 (행 우선, `matrix[0]`이 첫 번째 행) |
|
|
240
|
+
|
|
241
|
+
#### `setRecords(records)`
|
|
242
|
+
|
|
243
|
+
레코드 배열을 워크시트에 쓴다. 첫 번째 행(r=0)에 헤더가 자동 생성되고, 이후 행(r=1...)에 데이터가 기록된다. 모든 레코드의 필드를 수집하여 헤더로 사용한다.
|
|
244
|
+
|
|
245
|
+
| Parameter | Type | Description |
|
|
246
|
+
|-----------|------|-------------|
|
|
247
|
+
| `records` | `Record<string, ExcelValueType>[]` | 레코드 배열 |
|
|
248
|
+
|
|
249
|
+
### View Methods
|
|
250
|
+
|
|
251
|
+
#### `setZoom(percent)`
|
|
252
|
+
|
|
253
|
+
워크시트 확대/축소 비율을 설정한다.
|
|
254
|
+
|
|
255
|
+
| Parameter | Type | Description |
|
|
256
|
+
|-----------|------|-------------|
|
|
257
|
+
| `percent` | `number` | 확대/축소 퍼센트 |
|
|
258
|
+
|
|
259
|
+
#### `freezeAt(point)`
|
|
260
|
+
|
|
261
|
+
행/열 틀 고정을 설정한다.
|
|
262
|
+
|
|
263
|
+
| Parameter | Type | Description |
|
|
264
|
+
|-----------|------|-------------|
|
|
265
|
+
| `point.r` | `number \| undefined` | 고정할 행 인덱스 (0 기반) |
|
|
266
|
+
| `point.c` | `number \| undefined` | 고정할 열 인덱스 (0 기반) |
|
|
267
|
+
|
|
268
|
+
### Image Methods
|
|
269
|
+
|
|
270
|
+
#### `addImage(opts)`
|
|
271
|
+
|
|
272
|
+
워크시트에 이미지를 삽입한다. 같은 시트의 첫 이미지 호출 시 `drawing1.xml` 생성, 이후 이미지는 동일 drawing에 추가된다.
|
|
273
|
+
|
|
274
|
+
| Parameter | Type | Description |
|
|
275
|
+
|-----------|------|-------------|
|
|
276
|
+
| `opts.bytes` | `Bytes` | 이미지 바이너리 데이터 |
|
|
277
|
+
| `opts.ext` | `string` | 이미지 확장자 (예: `"png"`, `"jpg"`, `"gif"`) |
|
|
278
|
+
| `opts.from` | `{ r: number; c: number; rOff?: number \| string; cOff?: number \| string }` | 이미지 시작 위치. `r`/`c`는 0 기반 행/열 인덱스, `rOff`/`cOff`는 선택적 EMU 오프셋 |
|
|
279
|
+
| `opts.to` | `{ r: number; c: number; rOff?: number \| string; cOff?: number \| string } \| undefined` | 이미지 끝 위치. 생략 시 기본값은 `{ r: from.r + 1, c: from.c + 1 }`이다 |
|
|
280
|
+
|
|
281
|
+
**이미지 파일 관리:**
|
|
282
|
+
- 이미지는 `xl/media/image1.ext`, `xl/media/image2.ext` 등으로 자동 관리됨
|
|
283
|
+
- 기존 파일명과 중복되지 않도록 인덱스 자동 증가
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## `ExcelCell`
|
|
288
|
+
|
|
289
|
+
Excel 셀을 나타내는 클래스. 값 읽기/쓰기, 수식, 스타일, 셀 병합 기능을 제공한다. 모든 메서드가 `async`인 이유는 셀 타입에 따라 필요한 XML만 선택적으로 로드하는 Lazy Loading 아키텍처 때문이다.
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
export class ExcelCell {
|
|
293
|
+
readonly addr: ExcelAddressPoint;
|
|
294
|
+
|
|
295
|
+
constructor(zipCache: ZipCache, targetFileName: string, r: number, c: number);
|
|
296
|
+
|
|
297
|
+
// Value
|
|
298
|
+
async setValue(val: ExcelValueType): Promise<void>;
|
|
299
|
+
async getValue(): Promise<ExcelValueType>;
|
|
300
|
+
async setFormula(val: string | undefined): Promise<void>;
|
|
301
|
+
async getFormula(): Promise<string | undefined>;
|
|
302
|
+
|
|
303
|
+
// Merge
|
|
304
|
+
async merge(r: number, c: number): Promise<void>;
|
|
305
|
+
|
|
306
|
+
// Style
|
|
307
|
+
async getStyleId(): Promise<string | undefined>;
|
|
308
|
+
async setStyleId(styleId: string | undefined): Promise<void>;
|
|
309
|
+
async setStyle(opts: ExcelStyleOptions): Promise<void>;
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Properties
|
|
314
|
+
|
|
315
|
+
| Property | Type | Description |
|
|
316
|
+
|----------|------|-------------|
|
|
317
|
+
| `addr` | `ExcelAddressPoint` | 셀 주소 (0 기반 행/열 인덱스) |
|
|
318
|
+
|
|
319
|
+
### Value Methods
|
|
320
|
+
|
|
321
|
+
#### `setValue(val)`
|
|
322
|
+
|
|
323
|
+
셀 값을 설정한다. `undefined`를 전달하면 셀이 삭제된다. `DateOnly`, `DateTime`, `Time` 인스턴스를 전달하면 내부적으로 Excel 날짜 숫자로 변환하고 적절한 numFmt를 설정한다.
|
|
324
|
+
|
|
325
|
+
| Parameter | Type | Description |
|
|
326
|
+
|-----------|------|-------------|
|
|
327
|
+
| `val` | `ExcelValueType` | 셀 값 (`number \| string \| DateOnly \| DateTime \| Time \| boolean \| undefined`) |
|
|
328
|
+
|
|
329
|
+
#### `getValue()`
|
|
330
|
+
|
|
331
|
+
셀 값을 반환한다. 셀 타입과 스타일에 따라 적절한 JavaScript 타입으로 변환한다. 비어있는 셀은 `undefined`를 반환한다.
|
|
332
|
+
|
|
333
|
+
#### `setFormula(val)`
|
|
334
|
+
|
|
335
|
+
셀에 수식을 설정한다. `undefined`를 전달하면 수식이 제거된다.
|
|
336
|
+
|
|
337
|
+
| Parameter | Type | Description |
|
|
338
|
+
|-----------|------|-------------|
|
|
339
|
+
| `val` | `string \| undefined` | 수식 문자열 (예: `"SUM(A1:A10)"`) |
|
|
340
|
+
|
|
341
|
+
#### `getFormula()`
|
|
342
|
+
|
|
343
|
+
셀 수식을 반환한다. 수식이 없으면 `undefined`를 반환한다.
|
|
344
|
+
|
|
345
|
+
### Merge Methods
|
|
346
|
+
|
|
347
|
+
#### `merge(r, c)`
|
|
348
|
+
|
|
349
|
+
현재 셀에서 지정된 끝 좌표까지 셀을 병합한다.
|
|
350
|
+
|
|
351
|
+
| Parameter | Type | Description |
|
|
352
|
+
|-----------|------|-------------|
|
|
353
|
+
| `r` | `number` | 병합 끝 행 인덱스 (0 기반) |
|
|
354
|
+
| `c` | `number` | 병합 끝 열 인덱스 (0 기반) |
|
|
355
|
+
|
|
356
|
+
### Style Methods
|
|
357
|
+
|
|
358
|
+
#### `getStyleId()`
|
|
359
|
+
|
|
360
|
+
셀의 스타일 ID를 반환한다. 스타일이 없으면 `undefined`를 반환한다.
|
|
361
|
+
|
|
362
|
+
#### `setStyleId(styleId)`
|
|
363
|
+
|
|
364
|
+
셀의 스타일 ID를 직접 설정한다.
|
|
365
|
+
|
|
366
|
+
| Parameter | Type | Description |
|
|
367
|
+
|-----------|------|-------------|
|
|
368
|
+
| `styleId` | `string \| undefined` | 스타일 ID |
|
|
369
|
+
|
|
370
|
+
#### `setStyle(opts)`
|
|
371
|
+
|
|
372
|
+
셀 스타일을 설정한다. 기존 스타일이 있으면 클론 후 병합한다.
|
|
373
|
+
|
|
374
|
+
커스텀 Excel formatCode를 지정하려면 `numberFormatCode`를 사용한다:
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
await cell.setStyle({ numberFormatCode: "0.000000" }); // 소수점 6자리
|
|
378
|
+
await cell.setStyle({ numberFormatCode: "#,##0.00" }); // 천 단위 구분 + 2자리
|
|
379
|
+
await cell.setStyle({ numberFormatCode: "0.00%" }); // 퍼센트
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
`numberFormat`(프리셋)과 `numberFormatCode`(커스텀)가 동시에 지정되면 `numberFormatCode`가 우선 적용된다.
|
|
383
|
+
|
|
384
|
+
| Parameter | Type | Description |
|
|
385
|
+
|-----------|------|-------------|
|
|
386
|
+
| `opts` | `ExcelStyleOptions` | 스타일 옵션 (배경색, 테두리, 정렬, 숫자 형식) |
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## `ExcelRow`
|
|
391
|
+
|
|
392
|
+
Excel 워크시트의 행을 나타내는 클래스. 셀 접근 기능을 제공한다.
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
export class ExcelRow {
|
|
396
|
+
constructor(zipCache: ZipCache, targetFileName: string, r: number, cellFactory: (c: number) => ExcelCell);
|
|
397
|
+
|
|
398
|
+
cell(c: number): ExcelCell;
|
|
399
|
+
async getCells(): Promise<ExcelCell[]>;
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
### Methods
|
|
404
|
+
|
|
405
|
+
#### `cell(c)`
|
|
406
|
+
|
|
407
|
+
지정된 열 인덱스의 셀을 반환한다.
|
|
408
|
+
|
|
409
|
+
| Parameter | Type | Description |
|
|
410
|
+
|-----------|------|-------------|
|
|
411
|
+
| `c` | `number` | 열 인덱스 (0 기반) |
|
|
412
|
+
|
|
413
|
+
#### `getCells()`
|
|
414
|
+
|
|
415
|
+
행의 모든 셀을 배열로 반환한다. 데이터 범위 내의 모든 열에 대한 셀이 포함된다.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## `ExcelCol`
|
|
420
|
+
|
|
421
|
+
Excel 워크시트의 열을 나타내는 클래스. 셀 접근 및 열 너비 설정 기능을 제공한다.
|
|
422
|
+
|
|
423
|
+
```typescript
|
|
424
|
+
export class ExcelCol {
|
|
425
|
+
constructor(zipCache: ZipCache, targetFileName: string, c: number, cellFactory: (r: number) => ExcelCell);
|
|
426
|
+
|
|
427
|
+
cell(r: number): ExcelCell;
|
|
428
|
+
async getCells(): Promise<ExcelCell[]>;
|
|
429
|
+
async setWidth(size: number): Promise<void>;
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Methods
|
|
434
|
+
|
|
435
|
+
#### `cell(r)`
|
|
436
|
+
|
|
437
|
+
지정된 행 인덱스의 셀을 반환한다.
|
|
438
|
+
|
|
439
|
+
| Parameter | Type | Description |
|
|
440
|
+
|-----------|------|-------------|
|
|
441
|
+
| `r` | `number` | 행 인덱스 (0 기반) |
|
|
442
|
+
|
|
443
|
+
#### `getCells()`
|
|
444
|
+
|
|
445
|
+
열의 모든 셀을 배열로 반환한다. 데이터 범위 내의 모든 행에 대한 셀이 포함된다.
|
|
446
|
+
|
|
447
|
+
#### `setWidth(size)`
|
|
448
|
+
|
|
449
|
+
열 너비를 설정한다.
|
|
450
|
+
|
|
451
|
+
| Parameter | Type | Description |
|
|
452
|
+
|-----------|------|-------------|
|
|
453
|
+
| `size` | `number` | 열 너비 |
|
package/docs/types.md
ADDED
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
# Types
|
|
2
|
+
|
|
3
|
+
## Value Types
|
|
4
|
+
|
|
5
|
+
### `ExcelValueType`
|
|
6
|
+
|
|
7
|
+
셀에 저장할 수 있는 값의 타입이다.
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
export type ExcelValueType = number | string | DateOnly | DateTime | Time | boolean | undefined;
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### `ExcelNumberFormat`
|
|
14
|
+
|
|
15
|
+
숫자 형식 이름이다. `ExcelUtils`의 변환 메서드와 `ExcelStyleOptions.numberFormat`에서 사용한다.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
export type ExcelNumberFormat = "number" | "string" | "DateOnly" | "DateTime" | "Time";
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### `ExcelCellType`
|
|
22
|
+
|
|
23
|
+
Excel 셀 타입이다. XML의 `t` 속성에 대응한다.
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
export type ExcelCellType = "s" | "b" | "str" | "n" | "inlineStr" | "e";
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Value | Description |
|
|
30
|
+
|-------|-------------|
|
|
31
|
+
| `"s"` | 공유 문자열 (SharedString) |
|
|
32
|
+
| `"b"` | boolean |
|
|
33
|
+
| `"str"` | 수식 결과 문자열 |
|
|
34
|
+
| `"n"` | 숫자 |
|
|
35
|
+
| `"inlineStr"` | 인라인 문자열 (서식 있는 텍스트) |
|
|
36
|
+
| `"e"` | 에러 |
|
|
37
|
+
|
|
38
|
+
## Address Types
|
|
39
|
+
|
|
40
|
+
### `ExcelAddressPoint`
|
|
41
|
+
|
|
42
|
+
셀 좌표를 나타내는 인터페이스이다. 모든 좌표는 0 기반이다.
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
export interface ExcelAddressPoint {
|
|
46
|
+
r: number;
|
|
47
|
+
c: number;
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
| Field | Type | Description |
|
|
52
|
+
|-------|------|-------------|
|
|
53
|
+
| `r` | `number` | 행 인덱스 (0 기반) |
|
|
54
|
+
| `c` | `number` | 열 인덱스 (0 기반) |
|
|
55
|
+
|
|
56
|
+
### `ExcelAddressRangePoint`
|
|
57
|
+
|
|
58
|
+
셀 범위 좌표를 나타내는 인터페이스이다.
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
export interface ExcelAddressRangePoint {
|
|
62
|
+
s: ExcelAddressPoint;
|
|
63
|
+
e: ExcelAddressPoint;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Field | Type | Description |
|
|
68
|
+
|-------|------|-------------|
|
|
69
|
+
| `s` | `ExcelAddressPoint` | 시작 좌표 |
|
|
70
|
+
| `e` | `ExcelAddressPoint` | 끝 좌표 |
|
|
71
|
+
|
|
72
|
+
## Style Types
|
|
73
|
+
|
|
74
|
+
### `ExcelStyleOptions`
|
|
75
|
+
|
|
76
|
+
셀 스타일 옵션 인터페이스이다.
|
|
77
|
+
|
|
78
|
+
```typescript
|
|
79
|
+
export interface ExcelStyleOptions {
|
|
80
|
+
background?: string;
|
|
81
|
+
border?: ExcelBorderPosition[];
|
|
82
|
+
horizontalAlign?: ExcelHorizontalAlign;
|
|
83
|
+
verticalAlign?: ExcelVerticalAlign;
|
|
84
|
+
numberFormat?: ExcelNumberFormat;
|
|
85
|
+
numberFormatCode?: string;
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
| Field | Type | Description |
|
|
90
|
+
|-------|------|-------------|
|
|
91
|
+
| `background` | `string \| undefined` | 배경색 (ARGB 형식, 8자리 16진수. 예: `"00FF0000"` = 빨강. alpha는 반전 값) |
|
|
92
|
+
| `border` | `ExcelBorderPosition[] \| undefined` | 테두리 위치 배열 |
|
|
93
|
+
| `horizontalAlign` | `ExcelHorizontalAlign \| undefined` | 가로 정렬 |
|
|
94
|
+
| `verticalAlign` | `ExcelVerticalAlign \| undefined` | 세로 정렬 |
|
|
95
|
+
| `numberFormat` | `ExcelNumberFormat \| undefined` | 숫자 형식 프리셋 |
|
|
96
|
+
| `numberFormatCode` | `string \| undefined` | 커스텀 Excel formatCode 문자열 (예: `"0.000000"`, `"#,##0.00"`, `"0.00%"`) |
|
|
97
|
+
|
|
98
|
+
**우선순위:** `numberFormatCode`가 지정되면 `numberFormat`보다 우선 적용된다. 동일한 formatCode는 `numFmts`에 중복 등록되지 않는다.
|
|
99
|
+
|
|
100
|
+
### `ExcelBorderPosition`
|
|
101
|
+
|
|
102
|
+
테두리 위치를 나타내는 타입이다.
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
export type ExcelBorderPosition = "left" | "right" | "top" | "bottom";
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `ExcelHorizontalAlign`
|
|
109
|
+
|
|
110
|
+
가로 정렬을 나타내는 타입이다.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
export type ExcelHorizontalAlign = "center" | "left" | "right";
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `ExcelVerticalAlign`
|
|
117
|
+
|
|
118
|
+
세로 정렬을 나타내는 타입이다.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
export type ExcelVerticalAlign = "center" | "top" | "bottom";
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Excel XML Interface
|
|
125
|
+
|
|
126
|
+
### `ExcelXml`
|
|
127
|
+
|
|
128
|
+
XML 처리 클래스가 구현하는 인터페이스이다. 내부 구현에 사용되며, `xml/` 디렉터리의 클래스들이 이를 구현한다.
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
export interface ExcelXml {
|
|
132
|
+
readonly data: unknown;
|
|
133
|
+
cleanup(): void;
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
| Field | Type | Description |
|
|
138
|
+
|-------|------|-------------|
|
|
139
|
+
| `data` | `unknown` | XML 파싱된 데이터 |
|
|
140
|
+
| `cleanup()` | `() => void` | `ZipCache.toBytes()` 직전에 호출되어 직렬화 전 데이터를 정리한다 |
|
|
141
|
+
|
|
142
|
+
## XML Data Types
|
|
143
|
+
|
|
144
|
+
아래 인터페이스들은 xlsx 내부 XML 파일의 데이터 구조를 타입으로 표현한 것이다. 주로 내부 구현에 사용된다.
|
|
145
|
+
|
|
146
|
+
### `ExcelXmlContentTypeData`
|
|
147
|
+
|
|
148
|
+
`[Content_Types].xml` 데이터 구조이다.
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
export interface ExcelXmlContentTypeData {
|
|
152
|
+
Types: {
|
|
153
|
+
$: { xmlns: string };
|
|
154
|
+
Default: { $: { Extension: string; ContentType: string } }[];
|
|
155
|
+
Override: { $: { PartName: string; ContentType: string } }[];
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
| Field | Type | Description |
|
|
161
|
+
|-------|------|-------------|
|
|
162
|
+
| `Types.$` | `{ xmlns: string }` | 네임스페이스 |
|
|
163
|
+
| `Types.Default` | `Array` | 확장자별 기본 콘텐트 타입 |
|
|
164
|
+
| `Types.Default.$.Extension` | `string` | 파일 확장자 |
|
|
165
|
+
| `Types.Default.$.ContentType` | `string` | MIME 타입 |
|
|
166
|
+
| `Types.Override` | `Array` | 파일별 오버라이드 콘텐트 타입 |
|
|
167
|
+
| `Types.Override.$.PartName` | `string` | 파일 경로 |
|
|
168
|
+
| `Types.Override.$.ContentType` | `string` | MIME 타입 |
|
|
169
|
+
|
|
170
|
+
### `ExcelXmlRelationshipData`
|
|
171
|
+
|
|
172
|
+
`*.rels` 파일 데이터 구조이다.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
export interface ExcelXmlRelationshipData {
|
|
176
|
+
Relationships: {
|
|
177
|
+
$: { xmlns: string };
|
|
178
|
+
Relationship?: ExcelRelationshipData[];
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
| Field | Type | Description |
|
|
184
|
+
|-------|------|-------------|
|
|
185
|
+
| `Relationships.$` | `{ xmlns: string }` | 네임스페이스 |
|
|
186
|
+
| `Relationships.Relationship` | `ExcelRelationshipData[] \| undefined` | 관계 항목 배열 |
|
|
187
|
+
|
|
188
|
+
### `ExcelRelationshipData`
|
|
189
|
+
|
|
190
|
+
개별 Relationship 엔트리 데이터이다.
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
export interface ExcelRelationshipData {
|
|
194
|
+
$: {
|
|
195
|
+
Id: string;
|
|
196
|
+
Target: string;
|
|
197
|
+
Type: string;
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
| Field | Type | Description |
|
|
203
|
+
|-------|------|-------------|
|
|
204
|
+
| `$.Id` | `string` | 관계 ID (예: `"rId1"`) |
|
|
205
|
+
| `$.Target` | `string` | 대상 파일 경로 |
|
|
206
|
+
| `$.Type` | `string` | 관계 타입 URI |
|
|
207
|
+
|
|
208
|
+
### `ExcelXmlWorkbookData`
|
|
209
|
+
|
|
210
|
+
`workbook.xml` 데이터 구조이다.
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
export interface ExcelXmlWorkbookData {
|
|
214
|
+
workbook: {
|
|
215
|
+
$: { "xmlns": string; "xmlns:r"?: string };
|
|
216
|
+
bookViews?: [{ workbookView: [{}] }];
|
|
217
|
+
sheets?: [{ sheet: { $: { "name": string; "sheetId": string; "r:id": string } }[] }];
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
| Field | Type | Description |
|
|
223
|
+
|-------|------|-------------|
|
|
224
|
+
| `workbook.$` | `object` | 네임스페이스 |
|
|
225
|
+
| `workbook.bookViews` | `Array \| undefined` | 워크북 뷰 설정 |
|
|
226
|
+
| `workbook.sheets` | `Array \| undefined` | 시트 목록 |
|
|
227
|
+
| `workbook.sheets[0].sheet[].$.name` | `string` | 시트 이름 |
|
|
228
|
+
| `workbook.sheets[0].sheet[].$.sheetId` | `string` | 시트 ID |
|
|
229
|
+
| `workbook.sheets[0].sheet[].$["r:id"]` | `string` | 관계 ID |
|
|
230
|
+
|
|
231
|
+
### `ExcelXmlWorksheetData`
|
|
232
|
+
|
|
233
|
+
`worksheet*.xml` 데이터 구조이다.
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
export interface ExcelXmlWorksheetData {
|
|
237
|
+
worksheet: {
|
|
238
|
+
$: { "xmlns": string; "xmlns:r"?: string };
|
|
239
|
+
dimension?: [{ $: { ref: string } }];
|
|
240
|
+
sheetViews?: [{ sheetView: { $: { workbookViewId: string; zoomScale?: string }; pane?: [...] }[] }];
|
|
241
|
+
sheetFormatPr?: [{ $: { defaultRowHeight: string } }];
|
|
242
|
+
cols?: [{ col: { $: { min: string; max: string; width?: string; bestFit?: string; customWidth?: string } }[] }];
|
|
243
|
+
sheetData: [{ row?: ExcelRowData[] }];
|
|
244
|
+
mergeCells?: [{ $: { count: string }; mergeCell: { $: { ref: string } }[] }];
|
|
245
|
+
drawing?: { $: { "r:id": string } }[];
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
| Field | Type | Description |
|
|
251
|
+
|-------|------|-------------|
|
|
252
|
+
| `worksheet.dimension` | `Array \| undefined` | 데이터 범위 (예: `"A1:C10"`) |
|
|
253
|
+
| `worksheet.sheetViews` | `Array \| undefined` | 시트 뷰 설정 (줌, 틀 고정) |
|
|
254
|
+
| `worksheet.sheetFormatPr` | `Array \| undefined` | 기본 행 높이 |
|
|
255
|
+
| `worksheet.cols` | `Array \| undefined` | 열 설정 (너비 등) |
|
|
256
|
+
| `worksheet.sheetData` | `Array` | 행 데이터 |
|
|
257
|
+
| `worksheet.mergeCells` | `Array \| undefined` | 병합 셀 정보 |
|
|
258
|
+
| `worksheet.drawing` | `Array \| undefined` | 드로잉 관계 참조 |
|
|
259
|
+
|
|
260
|
+
### `ExcelRowData`
|
|
261
|
+
|
|
262
|
+
행 XML 데이터이다.
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
export interface ExcelRowData {
|
|
266
|
+
$: { r: string };
|
|
267
|
+
c?: ExcelCellData[];
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
| Field | Type | Description |
|
|
272
|
+
|-------|------|-------------|
|
|
273
|
+
| `$.r` | `string` | 행 주소 (1 기반, 예: `"1"`, `"10"`) |
|
|
274
|
+
| `c` | `ExcelCellData[] \| undefined` | 셀 데이터 배열 |
|
|
275
|
+
|
|
276
|
+
### `ExcelCellData`
|
|
277
|
+
|
|
278
|
+
셀 XML 데이터이다.
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
export interface ExcelCellData {
|
|
282
|
+
$: { r: string; s?: string; t?: ExcelCellType };
|
|
283
|
+
v?: [string];
|
|
284
|
+
f?: [string];
|
|
285
|
+
is?: { t?: (string | { _?: string })[] }[];
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
| Field | Type | Description |
|
|
290
|
+
|-------|------|-------------|
|
|
291
|
+
| `$.r` | `string` | 셀 주소 (예: `"A1"`, `"B3"`) |
|
|
292
|
+
| `$.s` | `string \| undefined` | 스타일 ID |
|
|
293
|
+
| `$.t` | `ExcelCellType \| undefined` | 셀 타입 |
|
|
294
|
+
| `v` | `[string] \| undefined` | 셀 값 |
|
|
295
|
+
| `f` | `[string] \| undefined` | 수식 |
|
|
296
|
+
| `is` | `Array \| undefined` | 인라인 문자열 데이터 |
|
|
297
|
+
|
|
298
|
+
### `ExcelXmlDrawingData`
|
|
299
|
+
|
|
300
|
+
`drawing*.xml` 데이터 구조이다. 이미지 앵커 정보를 포함한다.
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
export interface ExcelXmlDrawingData {
|
|
304
|
+
wsDr: {
|
|
305
|
+
$: { "xmlns": string; "xmlns:a"?: string; "xmlns:r"?: string };
|
|
306
|
+
twoCellAnchor?: {
|
|
307
|
+
from?: { col: string[]; colOff?: string[]; row: string[]; rowOff?: string[] }[];
|
|
308
|
+
to?: { col: string[]; colOff?: string[]; row: string[]; rowOff?: string[] }[];
|
|
309
|
+
pic?: { nvPicPr?: {...}[]; blipFill?: {...}[]; spPr?: {...}[] }[];
|
|
310
|
+
clientData?: unknown[];
|
|
311
|
+
}[];
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
| Field | Type | Description |
|
|
317
|
+
|-------|------|-------------|
|
|
318
|
+
| `wsDr.$` | `object` | 네임스페이스 |
|
|
319
|
+
| `wsDr.twoCellAnchor` | `Array \| undefined` | 두 셀 사이에 앵커된 이미지 목록 |
|
|
320
|
+
| `twoCellAnchor.from` | `Array \| undefined` | 시작 위치 (행/열/오프셋) |
|
|
321
|
+
| `twoCellAnchor.to` | `Array \| undefined` | 끝 위치 (행/열/오프셋) |
|
|
322
|
+
| `twoCellAnchor.pic` | `Array \| undefined` | 이미지 정보 (blip 관계 ID 포함) |
|
|
323
|
+
|
|
324
|
+
### `ExcelXmlSharedStringData`
|
|
325
|
+
|
|
326
|
+
`sharedStrings.xml` 데이터 구조이다.
|
|
327
|
+
|
|
328
|
+
```typescript
|
|
329
|
+
export interface ExcelXmlSharedStringData {
|
|
330
|
+
sst: {
|
|
331
|
+
$: { xmlns: string };
|
|
332
|
+
si?: ExcelXmlSharedStringDataSi[];
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
| Field | Type | Description |
|
|
338
|
+
|-------|------|-------------|
|
|
339
|
+
| `sst.$` | `{ xmlns: string }` | 네임스페이스 |
|
|
340
|
+
| `sst.si` | `ExcelXmlSharedStringDataSi[] \| undefined` | 공유 문자열 항목 배열 |
|
|
341
|
+
|
|
342
|
+
### `ExcelXmlSharedStringDataSi`
|
|
343
|
+
|
|
344
|
+
SharedString 개별 항목이다. discriminated union으로, `t` 키가 있으면 단순 텍스트, `r` 키가 있으면 서식 있는 텍스트(rich text)이다.
|
|
345
|
+
|
|
346
|
+
```typescript
|
|
347
|
+
export type ExcelXmlSharedStringDataSi =
|
|
348
|
+
| { t: ExcelXmlSharedStringDataText }
|
|
349
|
+
| { r: { t: ExcelXmlSharedStringDataText }[] };
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
| Variant | Discriminant | Description |
|
|
353
|
+
|---------|-------------|-------------|
|
|
354
|
+
| `{ t: ... }` | `t` 키 존재 | 단순 텍스트 |
|
|
355
|
+
| `{ r: ... }` | `r` 키 존재 | 서식 있는 텍스트 (run 배열) |
|
|
356
|
+
|
|
357
|
+
### `ExcelXmlSharedStringDataText`
|
|
358
|
+
|
|
359
|
+
SharedString 텍스트 데이터이다. 단순 문자열 또는 공백 보존 속성이 있는 객체이다.
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
export type ExcelXmlSharedStringDataText = [string | { $: { space?: "preserve" }; _?: string }];
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### `ExcelXmlStyleData`
|
|
366
|
+
|
|
367
|
+
`styles.xml` 데이터 구조이다.
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
export interface ExcelXmlStyleData {
|
|
371
|
+
styleSheet: {
|
|
372
|
+
$: { xmlns: string };
|
|
373
|
+
numFmts?: [{ $: { count: string }; numFmt?: { $: { numFmtId: string; formatCode: string } }[] }];
|
|
374
|
+
fonts: [{ $: { count: string }; font: {}[] }];
|
|
375
|
+
fills: [{ $: { count: string }; fill: ExcelXmlStyleDataFill[] }];
|
|
376
|
+
borders: [{ $: { count: string }; border: ExcelXmlStyleDataBorder[] }];
|
|
377
|
+
cellXfs: [{ $: { count: string }; xf: ExcelXmlStyleDataXf[] }];
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
| Field | Type | Description |
|
|
383
|
+
|-------|------|-------------|
|
|
384
|
+
| `styleSheet.numFmts` | `Array \| undefined` | 커스텀 숫자 형식 목록 |
|
|
385
|
+
| `styleSheet.fonts` | `Array` | 폰트 목록 |
|
|
386
|
+
| `styleSheet.fills` | `Array` | 채우기 스타일 목록 |
|
|
387
|
+
| `styleSheet.borders` | `Array` | 테두리 스타일 목록 |
|
|
388
|
+
| `styleSheet.cellXfs` | `Array` | 셀 서식(xf) 목록 |
|
|
389
|
+
|
|
390
|
+
### `ExcelXmlStyleDataXf`
|
|
391
|
+
|
|
392
|
+
셀 서식(xf) 데이터이다.
|
|
393
|
+
|
|
394
|
+
```typescript
|
|
395
|
+
export interface ExcelXmlStyleDataXf {
|
|
396
|
+
$: {
|
|
397
|
+
numFmtId?: string;
|
|
398
|
+
fontId?: string;
|
|
399
|
+
fillId?: string;
|
|
400
|
+
borderId?: string;
|
|
401
|
+
xfId?: string;
|
|
402
|
+
applyNumberFormat?: string;
|
|
403
|
+
applyFont?: string;
|
|
404
|
+
applyAlignment?: string;
|
|
405
|
+
applyFill?: string;
|
|
406
|
+
applyBorder?: string;
|
|
407
|
+
};
|
|
408
|
+
alignment?: [{ $: { horizontal?: "center" | "left" | "right"; vertical?: "center" | "top" | "bottom" } }];
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
| Field | Type | Description |
|
|
413
|
+
|-------|------|-------------|
|
|
414
|
+
| `$.numFmtId` | `string \| undefined` | 숫자 형식 ID |
|
|
415
|
+
| `$.fontId` | `string \| undefined` | 폰트 ID |
|
|
416
|
+
| `$.fillId` | `string \| undefined` | 채우기 ID |
|
|
417
|
+
| `$.borderId` | `string \| undefined` | 테두리 ID |
|
|
418
|
+
| `$.xfId` | `string \| undefined` | 부모 xf ID |
|
|
419
|
+
| `$.applyNumberFormat` | `string \| undefined` | 숫자 형식 적용 여부 |
|
|
420
|
+
| `$.applyFont` | `string \| undefined` | 폰트 적용 여부 |
|
|
421
|
+
| `$.applyAlignment` | `string \| undefined` | 정렬 적용 여부 |
|
|
422
|
+
| `$.applyFill` | `string \| undefined` | 채우기 적용 여부 |
|
|
423
|
+
| `$.applyBorder` | `string \| undefined` | 테두리 적용 여부 |
|
|
424
|
+
| `alignment` | `Array \| undefined` | 정렬 설정 (horizontal, vertical) |
|
|
425
|
+
|
|
426
|
+
### `ExcelXmlStyleDataFill`
|
|
427
|
+
|
|
428
|
+
채우기 스타일 데이터이다.
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
export interface ExcelXmlStyleDataFill {
|
|
432
|
+
patternFill: [{ $: { patternType: "none" | "solid" | "gray125" }; fgColor?: [{ $: { rgb: string } }] }];
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
| Field | Type | Description |
|
|
437
|
+
|-------|------|-------------|
|
|
438
|
+
| `patternFill[0].$.patternType` | `"none" \| "solid" \| "gray125"` | 패턴 유형 |
|
|
439
|
+
| `patternFill[0].fgColor` | `[{ $: { rgb: string } }] \| undefined` | 전경색 (ARGB) |
|
|
440
|
+
|
|
441
|
+
### `ExcelXmlStyleDataBorder`
|
|
442
|
+
|
|
443
|
+
테두리 스타일 데이터이다. 각 방향은 선택적이며, `style`과 `color`를 가진다.
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
export interface ExcelXmlStyleDataBorder {
|
|
447
|
+
top?: [{ $: { style: "thin" | "medium" }; color?: [{ $: { rgb: string } }] }];
|
|
448
|
+
left?: [{ $: { style: "thin" | "medium" }; color?: [{ $: { rgb: string } }] }];
|
|
449
|
+
right?: [{ $: { style: "thin" | "medium" }; color?: [{ $: { rgb: string } }] }];
|
|
450
|
+
bottom?: [{ $: { style: "thin" | "medium" }; color?: [{ $: { rgb: string } }] }];
|
|
451
|
+
}
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
| Field | Type | Description |
|
|
455
|
+
|-------|------|-------------|
|
|
456
|
+
| `top` | `Array \| undefined` | 상단 테두리 (`"thin"` 또는 `"medium"`) |
|
|
457
|
+
| `left` | `Array \| undefined` | 좌측 테두리 |
|
|
458
|
+
| `right` | `Array \| undefined` | 우측 테두리 |
|
|
459
|
+
| `bottom` | `Array \| undefined` | 하단 테두리 |
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Utilities
|
|
2
|
+
|
|
3
|
+
## `ExcelUtils`
|
|
4
|
+
|
|
5
|
+
Excel 유틸리티 함수 모음. 셀 주소 변환, 날짜/숫자 변환, 숫자 형식 처리 정적 메서드를 제공한다.
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
export class ExcelUtils {
|
|
9
|
+
// 주소 변환
|
|
10
|
+
static stringifyAddr(point: ExcelAddressPoint): string;
|
|
11
|
+
static stringifyRowAddr(r: number): string;
|
|
12
|
+
static stringifyColAddr(c: number): string;
|
|
13
|
+
static parseRowAddr(addr: string): number;
|
|
14
|
+
static parseColAddr(addr: string): number;
|
|
15
|
+
static parseCellAddr(addr: string): ExcelAddressPoint;
|
|
16
|
+
static parseRangeAddr(rangeAddr: string): ExcelAddressRangePoint;
|
|
17
|
+
static stringifyRangeAddr(point: ExcelAddressRangePoint): string;
|
|
18
|
+
|
|
19
|
+
// 날짜/숫자 변환
|
|
20
|
+
static convertTimeTickToNumber(tick: number): number;
|
|
21
|
+
static convertNumberToTimeTick(value: number): number;
|
|
22
|
+
|
|
23
|
+
// 숫자 형식 처리
|
|
24
|
+
static convertNumFmtCodeToName(numFmtCode: string): ExcelNumberFormat;
|
|
25
|
+
static convertNumFmtIdToName(numFmtId: number): ExcelNumberFormat;
|
|
26
|
+
static convertNumFmtNameToId(numFmtName: ExcelNumberFormat): number;
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 주소 변환 메서드
|
|
31
|
+
|
|
32
|
+
#### `stringifyAddr(point)`
|
|
33
|
+
|
|
34
|
+
셀 좌표를 "A1" 형식 문자열로 변환한다.
|
|
35
|
+
|
|
36
|
+
| Parameter | Type | Description |
|
|
37
|
+
|-----------|------|-------------|
|
|
38
|
+
| `point` | `ExcelAddressPoint` | 셀 좌표 (`{ r: number; c: number }`) |
|
|
39
|
+
|
|
40
|
+
**반환값:** `string` - 예: `{ r: 0, c: 0 }` -> `"A1"`, `{ r: 2, c: 3 }` -> `"D3"`
|
|
41
|
+
|
|
42
|
+
#### `stringifyRowAddr(r)`
|
|
43
|
+
|
|
44
|
+
행 인덱스(0 기반)를 행 주소 문자열로 변환한다.
|
|
45
|
+
|
|
46
|
+
| Parameter | Type | Description |
|
|
47
|
+
|-----------|------|-------------|
|
|
48
|
+
| `r` | `number` | 행 인덱스 (0 기반) |
|
|
49
|
+
|
|
50
|
+
**반환값:** `string` - 예: `0` -> `"1"`, `9` -> `"10"`
|
|
51
|
+
|
|
52
|
+
#### `stringifyColAddr(c)`
|
|
53
|
+
|
|
54
|
+
열 인덱스(0 기반)를 열 주소 문자열로 변환한다. 열 인덱스는 0~16383 범위여야 한다.
|
|
55
|
+
|
|
56
|
+
| Parameter | Type | Description |
|
|
57
|
+
|-----------|------|-------------|
|
|
58
|
+
| `c` | `number` | 열 인덱스 (0 기반) |
|
|
59
|
+
|
|
60
|
+
**반환값:** `string` - 예: `0` -> `"A"`, `25` -> `"Z"`, `26` -> `"AA"`
|
|
61
|
+
|
|
62
|
+
#### `parseRowAddr(addr)`
|
|
63
|
+
|
|
64
|
+
셀 주소에서 행 인덱스를 추출한다.
|
|
65
|
+
|
|
66
|
+
| Parameter | Type | Description |
|
|
67
|
+
|-----------|------|-------------|
|
|
68
|
+
| `addr` | `string` | 셀 주소 (예: `"A3"`) |
|
|
69
|
+
|
|
70
|
+
**반환값:** `number` - 0 기반 행 인덱스. 예: `"A3"` -> `2`
|
|
71
|
+
|
|
72
|
+
#### `parseColAddr(addr)`
|
|
73
|
+
|
|
74
|
+
셀 주소에서 열 인덱스를 추출한다.
|
|
75
|
+
|
|
76
|
+
| Parameter | Type | Description |
|
|
77
|
+
|-----------|------|-------------|
|
|
78
|
+
| `addr` | `string` | 셀 주소 (예: `"B3"`) |
|
|
79
|
+
|
|
80
|
+
**반환값:** `number` - 0 기반 열 인덱스. 예: `"B3"` -> `1`
|
|
81
|
+
|
|
82
|
+
#### `parseCellAddr(addr)`
|
|
83
|
+
|
|
84
|
+
셀 주소를 좌표로 변환한다.
|
|
85
|
+
|
|
86
|
+
| Parameter | Type | Description |
|
|
87
|
+
|-----------|------|-------------|
|
|
88
|
+
| `addr` | `string` | 셀 주소 (예: `"B3"`) |
|
|
89
|
+
|
|
90
|
+
**반환값:** `ExcelAddressPoint` - 예: `"B3"` -> `{ r: 2, c: 1 }`
|
|
91
|
+
|
|
92
|
+
#### `parseRangeAddr(rangeAddr)`
|
|
93
|
+
|
|
94
|
+
범위 주소를 좌표로 변환한다.
|
|
95
|
+
|
|
96
|
+
| Parameter | Type | Description |
|
|
97
|
+
|-----------|------|-------------|
|
|
98
|
+
| `rangeAddr` | `string` | 범위 주소 (예: `"A1:C3"`) |
|
|
99
|
+
|
|
100
|
+
**반환값:** `ExcelAddressRangePoint` - 예: `"A1:C3"` -> `{ s: { r: 0, c: 0 }, e: { r: 2, c: 2 } }`
|
|
101
|
+
|
|
102
|
+
#### `stringifyRangeAddr(point)`
|
|
103
|
+
|
|
104
|
+
범위 좌표를 주소 문자열로 변환한다. 시작과 끝이 같으면 단일 셀 주소를 반환한다.
|
|
105
|
+
|
|
106
|
+
| Parameter | Type | Description |
|
|
107
|
+
|-----------|------|-------------|
|
|
108
|
+
| `point` | `ExcelAddressRangePoint` | 범위 좌표 |
|
|
109
|
+
|
|
110
|
+
**반환값:** `string` - 예: `"A1:C3"` 또는 `"A1"` (단일 셀)
|
|
111
|
+
|
|
112
|
+
### 날짜/숫자 변환 메서드
|
|
113
|
+
|
|
114
|
+
#### `convertTimeTickToNumber(tick)`
|
|
115
|
+
|
|
116
|
+
JavaScript 타임스탬프(ms)를 Excel 날짜 숫자로 변환한다. Excel은 1900-01-01을 1로 계산한다 (1899-12-30이 날짜 0).
|
|
117
|
+
|
|
118
|
+
| Parameter | Type | Description |
|
|
119
|
+
|-----------|------|-------------|
|
|
120
|
+
| `tick` | `number` | JavaScript 타임스탬프 (밀리초) |
|
|
121
|
+
|
|
122
|
+
**반환값:** `number` - Excel 날짜 숫자
|
|
123
|
+
|
|
124
|
+
#### `convertNumberToTimeTick(value)`
|
|
125
|
+
|
|
126
|
+
Excel 날짜 숫자를 JavaScript 타임스탬프(ms)로 변환한다.
|
|
127
|
+
|
|
128
|
+
| Parameter | Type | Description |
|
|
129
|
+
|-----------|------|-------------|
|
|
130
|
+
| `value` | `number` | Excel 날짜 숫자 |
|
|
131
|
+
|
|
132
|
+
**반환값:** `number` - JavaScript 타임스탬프 (밀리초)
|
|
133
|
+
|
|
134
|
+
### 숫자 형식 처리 메서드
|
|
135
|
+
|
|
136
|
+
#### `convertNumFmtCodeToName(numFmtCode)`
|
|
137
|
+
|
|
138
|
+
숫자 형식 코드를 형식 이름으로 변환한다.
|
|
139
|
+
|
|
140
|
+
| Parameter | Type | Description |
|
|
141
|
+
|-----------|------|-------------|
|
|
142
|
+
| `numFmtCode` | `string` | 숫자 형식 코드 (예: `"General"`, `"yyyy-mm-dd"`) |
|
|
143
|
+
|
|
144
|
+
**반환값:** `ExcelNumberFormat` - `"number"`, `"string"`, `"DateOnly"`, `"DateTime"`, `"Time"` 중 하나
|
|
145
|
+
|
|
146
|
+
**변환 규칙:**
|
|
147
|
+
|
|
148
|
+
| 형식 코드 패턴 | 반환값 |
|
|
149
|
+
|----------------|--------|
|
|
150
|
+
| `"General"` | `"number"` |
|
|
151
|
+
| `yy`, `dd`, `mm`(날짜 문맥) 포함 + 시간 포함 | `"DateTime"` |
|
|
152
|
+
| `yy`, `dd`, `mm`(날짜 문맥) 포함 | `"DateOnly"` |
|
|
153
|
+
| `h`, `ss` 포함 | `"Time"` |
|
|
154
|
+
| 숫자 패턴 (`0`, `#`, `.` 등) | `"number"` |
|
|
155
|
+
|
|
156
|
+
#### `convertNumFmtIdToName(numFmtId)`
|
|
157
|
+
|
|
158
|
+
Excel 내장 숫자 형식 ID를 형식 이름으로 변환한다.
|
|
159
|
+
|
|
160
|
+
| Parameter | Type | Description |
|
|
161
|
+
|-----------|------|-------------|
|
|
162
|
+
| `numFmtId` | `number` | 숫자 형식 ID |
|
|
163
|
+
|
|
164
|
+
**반환값:** `ExcelNumberFormat`
|
|
165
|
+
|
|
166
|
+
**내장 형식 ID 범위:**
|
|
167
|
+
|
|
168
|
+
| ID 범위 | 형식 |
|
|
169
|
+
|---------|------|
|
|
170
|
+
| 0~13, 37~40, 48 | `"number"` (숫자/일반/통화/퍼센트) |
|
|
171
|
+
| 14~17, 27~31, 34~36, 50~58 | `"DateOnly"` (날짜, 로컬라이즈 포함) |
|
|
172
|
+
| 22 | `"DateTime"` (날짜+시간) |
|
|
173
|
+
| 18~21, 32~33, 45~47 | `"Time"` (시간) |
|
|
174
|
+
| 49 | `"string"` (텍스트) |
|
|
175
|
+
|
|
176
|
+
#### `convertNumFmtNameToId(numFmtName)`
|
|
177
|
+
|
|
178
|
+
숫자 형식 이름을 형식 ID로 변환한다.
|
|
179
|
+
|
|
180
|
+
| Parameter | Type | Description |
|
|
181
|
+
|-----------|------|-------------|
|
|
182
|
+
| `numFmtName` | `ExcelNumberFormat` | 형식 이름 |
|
|
183
|
+
|
|
184
|
+
**반환값:** `number`
|
|
185
|
+
|
|
186
|
+
**매핑:**
|
|
187
|
+
|
|
188
|
+
| 형식 이름 | ID |
|
|
189
|
+
|-----------|-----|
|
|
190
|
+
| `"number"` | 0 |
|
|
191
|
+
| `"DateOnly"` | 14 |
|
|
192
|
+
| `"DateTime"` | 22 |
|
|
193
|
+
| `"Time"` | 18 |
|
|
194
|
+
| `"string"` | 49 |
|
package/docs/wrapper.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Wrapper
|
|
2
|
+
|
|
3
|
+
## `ExcelWrapper`
|
|
4
|
+
|
|
5
|
+
Zod 스키마 기반 타입 안전한 Excel 읽기/쓰기 래퍼. 스키마에서 타입 정보를 추론하여 타입 안전한 읽기/쓰기를 제공한다.
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
export class ExcelWrapper<TSchema extends z.ZodObject<z.ZodRawShape>> {
|
|
9
|
+
constructor(schema: TSchema);
|
|
10
|
+
|
|
11
|
+
async read(
|
|
12
|
+
file: Bytes | Blob,
|
|
13
|
+
wsNameOrIndex?: string | number,
|
|
14
|
+
options?: { excludes?: (keyof z.infer<TSchema>)[] },
|
|
15
|
+
): Promise<z.infer<TSchema>[]>;
|
|
16
|
+
|
|
17
|
+
async write(
|
|
18
|
+
wsName: string,
|
|
19
|
+
records: Partial<z.infer<TSchema>>[],
|
|
20
|
+
options?: { excludes?: (keyof z.infer<TSchema>)[] },
|
|
21
|
+
): Promise<ExcelWorkbook>;
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Constructor
|
|
26
|
+
|
|
27
|
+
| Parameter | Type | Description |
|
|
28
|
+
|-----------|------|-------------|
|
|
29
|
+
| `schema` | `TSchema extends z.ZodObject<z.ZodRawShape>` | Zod 스키마. `.describe()`로 Excel 헤더 이름을 지정한다 |
|
|
30
|
+
|
|
31
|
+
### Methods
|
|
32
|
+
|
|
33
|
+
#### `read(file, wsNameOrIndex?, options?)`
|
|
34
|
+
|
|
35
|
+
Excel 파일을 레코드 배열로 읽는다. 헤더 행의 텍스트를 스키마의 `.describe()` 값과 매칭하여 필드를 연결한다. Zod 스키마로 유효성 검사를 수행하며, 실패 시 에러를 던진다.
|
|
36
|
+
|
|
37
|
+
| Parameter | Type | Description |
|
|
38
|
+
|-----------|------|-------------|
|
|
39
|
+
| `file` | `Bytes \| Blob` | Excel 파일 데이터 |
|
|
40
|
+
| `wsNameOrIndex` | `string \| number` | 워크시트 이름 또는 0 기반 인덱스 (기본값: `0`) |
|
|
41
|
+
| `options.excludes` | `(keyof z.infer<TSchema>)[]` | 읽기에서 제외할 필드 키 배열 |
|
|
42
|
+
|
|
43
|
+
**반환값:** `z.infer<TSchema>[]` - 스키마 타입으로 추론된 레코드 배열
|
|
44
|
+
|
|
45
|
+
**타입 변환 규칙:**
|
|
46
|
+
|
|
47
|
+
| 스키마 타입 | 변환 동작 |
|
|
48
|
+
|------------|-----------|
|
|
49
|
+
| `z.string()` | 문자열로 변환 (`String(rawValue)`) |
|
|
50
|
+
| `z.number()` | 숫자로 파싱 (`num.parseFloat`) |
|
|
51
|
+
| `z.boolean()` | `"1"`, `"true"` -> `true`, `"0"`, `"false"` -> `false` |
|
|
52
|
+
| `z.optional()` / `z.nullable()` | 빈 셀을 `undefined`로 반환 |
|
|
53
|
+
| `z.default(value)` | 빈 셀에 기본값 적용 |
|
|
54
|
+
| `DateOnly` / `DateTime` / `Time` | `instanceof`로 직접 전달 |
|
|
55
|
+
|
|
56
|
+
#### `write(wsName, records, options?)`
|
|
57
|
+
|
|
58
|
+
레코드 배열을 Excel 워크북으로 변환한다. 반환된 `ExcelWorkbook`의 리소스 관리는 호출자의 책임이다. 내부에서 에러 발생 시 워크북이 자동으로 `close()`된다.
|
|
59
|
+
|
|
60
|
+
| Parameter | Type | Description |
|
|
61
|
+
|-----------|------|-------------|
|
|
62
|
+
| `wsName` | `string` | 워크시트 이름 |
|
|
63
|
+
| `records` | `Partial<z.infer<TSchema>>[]` | 레코드 배열 |
|
|
64
|
+
| `options.excludes` | `(keyof z.infer<TSchema>)[]` | 쓰기에서 제외할 필드 키 배열 |
|
|
65
|
+
|
|
66
|
+
**반환값:** `ExcelWorkbook` - 호출자가 `try-finally` 블록에서 `close()`를 호출하여 리소스를 관리해야 한다
|
|
67
|
+
|
|
68
|
+
**쓰기 동작:**
|
|
69
|
+
|
|
70
|
+
- 첫 번째 행에 헤더 자동 생성 (스키마의 `.describe()` 값 사용)
|
|
71
|
+
- 모든 셀에 테두리 스타일 자동 적용
|
|
72
|
+
- 필수 비boolean 필드의 헤더에 노란색 배경(`00FFFF00`) 강조
|
|
73
|
+
- 확대/축소 85%, 첫 번째 행 틀 고정 자동 설정
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/excel",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.49",
|
|
4
4
|
"description": "심플리즘 패키지 - 엑셀 (neutral)",
|
|
5
5
|
"author": "심플리즘",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -14,7 +14,8 @@
|
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
-
"src"
|
|
17
|
+
"src",
|
|
18
|
+
"docs"
|
|
18
19
|
],
|
|
19
20
|
"sideEffects": false,
|
|
20
21
|
"devDependencies": {
|
|
@@ -23,6 +24,6 @@
|
|
|
23
24
|
"dependencies": {
|
|
24
25
|
"mime": "^4.1.0",
|
|
25
26
|
"zod": "^4.3.6",
|
|
26
|
-
"@simplysm/core-common": "14.0.
|
|
27
|
+
"@simplysm/core-common": "14.0.49"
|
|
27
28
|
}
|
|
28
29
|
}
|
|
@@ -120,7 +120,7 @@ export class ExcelXmlWorkbook implements ExcelXml {
|
|
|
120
120
|
}
|
|
121
121
|
|
|
122
122
|
private _getReplacedName(name: string): string {
|
|
123
|
-
//-- 잘못된 시트 이름
|
|
124
|
-
return name.replace(/[:\\/?*\[\]']/g, "
|
|
123
|
+
//-- 잘못된 시트 이름 문자 제거. 전부 제거되어 빈 문자열이 되면 "Sheet" 사용.
|
|
124
|
+
return name.replace(/[:\\/?*\[\]']/g, "") || "Sheet";
|
|
125
125
|
}
|
|
126
126
|
}
|