@simplysm/excel 13.0.96 → 13.0.98
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 +35 -361
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,400 +1,74 @@
|
|
|
1
1
|
# @simplysm/excel
|
|
2
2
|
|
|
3
|
-
Excel
|
|
3
|
+
Excel file processing library. Platform-neutral (works in both browser and Node.js).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @simplysm/excel
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## 아키텍처
|
|
14
|
-
|
|
15
|
-
ZIP 내부의 XML을 지연 로딩(Lazy Loading)하여 필요한 시점에만 파싱한다. 대용량 SharedStrings나 Styles XML이 있어도 해당 셀에 접근할 때만 로드되므로 메모리 효율적이다.
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
ExcelWorkbook (워크북)
|
|
19
|
-
├── ExcelWorksheet (워크시트)
|
|
20
|
-
│ ├── ExcelRow (행) → ExcelCell (셀)
|
|
21
|
-
│ └── ExcelCol (열) → ExcelCell (셀)
|
|
22
|
-
├── ZipCache (ZIP 파일 캐시, 지연 로딩)
|
|
23
|
-
└── ExcelWrapper (Zod 스키마 기반 래퍼)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
**모든 행/열/셀 인덱스는 0-based이다.**
|
|
27
|
-
|
|
28
|
-
## 리소스 관리
|
|
29
|
-
|
|
30
|
-
ExcelWorkbook은 내부적으로 ZIP 리소스를 관리하므로, 사용 후 반드시 리소스를 해제해야 한다.
|
|
11
|
+
## Exports
|
|
31
12
|
|
|
32
13
|
```typescript
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const ws = await wb.getWorksheet(0);
|
|
43
|
-
// ... 작업 수행
|
|
44
|
-
} finally {
|
|
45
|
-
await wb.close();
|
|
46
|
-
}
|
|
14
|
+
import {
|
|
15
|
+
ExcelWorkbook,
|
|
16
|
+
ExcelWorksheet,
|
|
17
|
+
ExcelRow,
|
|
18
|
+
ExcelCol,
|
|
19
|
+
ExcelCell,
|
|
20
|
+
ExcelUtils,
|
|
21
|
+
ExcelWrapper,
|
|
22
|
+
} from "@simplysm/excel";
|
|
47
23
|
```
|
|
48
24
|
|
|
49
|
-
##
|
|
25
|
+
## Quick Start
|
|
50
26
|
|
|
51
|
-
###
|
|
27
|
+
### Create a new workbook
|
|
52
28
|
|
|
53
29
|
```typescript
|
|
54
|
-
import { ExcelWorkbook } from "@simplysm/excel";
|
|
55
|
-
|
|
56
|
-
// 새 워크북 생성
|
|
57
30
|
await using wb = new ExcelWorkbook();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
await
|
|
61
|
-
await
|
|
31
|
+
const ws = await wb.addWorksheet("Sheet1");
|
|
32
|
+
await ws.cell(0, 0).setValue("Name");
|
|
33
|
+
await ws.cell(0, 1).setValue("Age");
|
|
34
|
+
await ws.cell(1, 0).setValue("Alice");
|
|
35
|
+
await ws.cell(1, 1).setValue(30);
|
|
36
|
+
const bytes = await wb.toBytes();
|
|
62
37
|
```
|
|
63
38
|
|
|
64
|
-
###
|
|
39
|
+
### Read an existing workbook
|
|
65
40
|
|
|
66
41
|
```typescript
|
|
67
|
-
|
|
68
|
-
const names = await wb.getWorksheetNames(); // string[]
|
|
69
|
-
|
|
70
|
-
// 워크시트 조회 (인덱스: 0-based)
|
|
42
|
+
await using wb = new ExcelWorkbook(fileBytes);
|
|
71
43
|
const ws = await wb.getWorksheet(0);
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
// 워크시트 추가
|
|
75
|
-
const ws = await wb.addWorksheet("새시트");
|
|
76
|
-
|
|
77
|
-
// 워크시트 이름 변경
|
|
78
|
-
await ws.setName("새이름");
|
|
79
|
-
const name = await ws.getName();
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### 파일 내보내기
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
const bytes = await wb.toBytes(); // Uint8Array (Bytes)
|
|
86
|
-
const blob = await wb.toBlob(); // Blob (MIME: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet)
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
## 워크시트 (ExcelWorksheet)
|
|
90
|
-
|
|
91
|
-
### 셀/행/열 접근
|
|
92
|
-
|
|
93
|
-
모든 인덱스는 0-based이다.
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
// 셀 접근
|
|
97
|
-
const cell = ws.cell(0, 0); // A1 (r=0, c=0)
|
|
98
|
-
|
|
99
|
-
// 행 접근
|
|
100
|
-
const row = ws.row(0); // 첫 번째 행
|
|
101
|
-
const cells = await row.getCells(); // 행의 모든 셀
|
|
102
|
-
|
|
103
|
-
// 열 접근
|
|
104
|
-
const col = ws.col(0); // 첫 번째 열
|
|
105
|
-
const cells = await col.getCells(); // 열의 모든 셀
|
|
106
|
-
|
|
107
|
-
// 열에서 특정 행의 셀
|
|
108
|
-
const cell = ws.col(2).cell(5); // C6
|
|
109
|
-
// 행에서 특정 열의 셀
|
|
110
|
-
const cell = ws.row(5).cell(2); // C6
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
### 데이터 범위
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
const range = await ws.getRange();
|
|
117
|
-
// { s: { r: 0, c: 0 }, e: { r: 9, c: 4 } }
|
|
118
|
-
|
|
119
|
-
// 모든 셀을 2차원 배열로
|
|
120
|
-
const cells = await ws.getCells(); // ExcelCell[][]
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### 행 복사
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
// 행 복사 (덮어쓰기)
|
|
127
|
-
await ws.copyRow(0, 5); // 0번 행을 5번 행으로 복사
|
|
128
|
-
|
|
129
|
-
// 삽입 복사 (기존 행은 아래로 밀림)
|
|
130
|
-
await ws.insertCopyRow(0, 5); // 0번 행을 5번 위치에 삽입 복사
|
|
131
|
-
|
|
132
|
-
// 행 스타일만 복사
|
|
133
|
-
await ws.copyRowStyle(0, 5);
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### 셀 복사
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
// 셀 복사 (값 + 스타일)
|
|
140
|
-
await ws.copyCell({ r: 0, c: 0 }, { r: 1, c: 1 });
|
|
141
|
-
|
|
142
|
-
// 셀 스타일만 복사
|
|
143
|
-
await ws.copyCellStyle({ r: 0, c: 0 }, { r: 1, c: 1 });
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### 뷰 설정
|
|
147
|
-
|
|
148
|
-
```typescript
|
|
149
|
-
// 줌 설정 (퍼센트)
|
|
150
|
-
await ws.setZoom(150);
|
|
151
|
-
|
|
152
|
-
// 틀고정 (r, c 모두 선택적)
|
|
153
|
-
await ws.freezeAt({ r: 1 }); // 1번 행 이후 고정 (첫 행 고정)
|
|
154
|
-
await ws.freezeAt({ c: 2 }); // 2번 열 이후 고정
|
|
155
|
-
await ws.freezeAt({ r: 1, c: 1 }); // 행+열 모두 고정
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
### 데이터 테이블
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
// 시트를 레코드 배열로 읽기
|
|
162
|
-
const data = await ws.getDataTable();
|
|
163
|
-
// Record<string, ExcelValueType>[]
|
|
164
|
-
|
|
165
|
-
// 옵션 지정
|
|
166
|
-
const data = await ws.getDataTable({
|
|
167
|
-
headerRowIndex: 0, // 헤더 행 인덱스 (기본: 범위의 첫 행)
|
|
168
|
-
checkEndColIndex: 0, // 이 열이 비어있으면 데이터 종료
|
|
169
|
-
usableHeaderNameFn: (name) => name !== "", // 사용할 헤더 필터
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
// 2차원 배열 쓰기
|
|
173
|
-
await ws.setDataMatrix([
|
|
174
|
-
["이름", "나이", "이메일"],
|
|
175
|
-
["Alice", 30, "alice@example.com"],
|
|
176
|
-
["Bob", 25, "bob@example.com"],
|
|
177
|
-
]);
|
|
178
|
-
|
|
179
|
-
// 레코드 배열 쓰기 (헤더 자동 생성)
|
|
180
|
-
await ws.setRecords([
|
|
181
|
-
{ name: "Alice", age: 30 },
|
|
182
|
-
{ name: "Bob", age: 25 },
|
|
183
|
-
]);
|
|
44
|
+
const value = await ws.cell(0, 0).getValue();
|
|
45
|
+
const dataTable = await ws.getDataTable();
|
|
184
46
|
```
|
|
185
47
|
|
|
186
|
-
###
|
|
48
|
+
### Type-safe read/write with Zod schema
|
|
187
49
|
|
|
188
50
|
```typescript
|
|
189
|
-
await ws.addImage({
|
|
190
|
-
bytes: imageBytes, // Uint8Array (이미지 바이너리)
|
|
191
|
-
ext: "png", // 확장자 (png, jpg 등)
|
|
192
|
-
from: { // 시작 위치 (0-based)
|
|
193
|
-
r: 0, c: 0,
|
|
194
|
-
rOff: 0, // 행 오프셋 (EMU 단위, 선택적)
|
|
195
|
-
cOff: 0, // 열 오프셋 (EMU 단위, 선택적)
|
|
196
|
-
},
|
|
197
|
-
to: { // 종료 위치 (생략 시 from + 1행 1열)
|
|
198
|
-
r: 5, c: 3,
|
|
199
|
-
rOff: 0,
|
|
200
|
-
cOff: 0,
|
|
201
|
-
},
|
|
202
|
-
});
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
## 셀 (ExcelCell)
|
|
206
|
-
|
|
207
|
-
### 값 읽기/쓰기
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
// 값 설정
|
|
211
|
-
await ws.cell(0, 0).setValue("텍스트");
|
|
212
|
-
await ws.cell(0, 1).setValue(1234);
|
|
213
|
-
await ws.cell(0, 2).setValue(true);
|
|
214
|
-
await ws.cell(0, 3).setValue(new DateOnly(2024, 1, 15));
|
|
215
|
-
await ws.cell(0, 4).setValue(new DateTime(2024, 1, 15, 10, 30));
|
|
216
|
-
await ws.cell(0, 5).setValue(new Time(10, 30, 0));
|
|
217
|
-
await ws.cell(0, 6).setValue(undefined); // 셀 삭제
|
|
218
|
-
|
|
219
|
-
// 값 읽기
|
|
220
|
-
const val = await ws.cell(0, 0).getValue();
|
|
221
|
-
// ExcelValueType = number | string | DateOnly | DateTime | Time | boolean | undefined
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### 수식
|
|
225
|
-
|
|
226
|
-
```typescript
|
|
227
|
-
await ws.cell(1, 0).setFormula("SUM(B1:B10)");
|
|
228
|
-
await ws.cell(1, 0).setFormula(undefined); // 수식 제거
|
|
229
|
-
|
|
230
|
-
const formula = await ws.cell(1, 0).getFormula(); // string | undefined
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### 셀 병합
|
|
234
|
-
|
|
235
|
-
```typescript
|
|
236
|
-
// cell(startR, startC).merge(endR, endC)
|
|
237
|
-
// 종료 좌표는 0-based 절대 좌표
|
|
238
|
-
await ws.cell(0, 0).merge(2, 2); // A1:C3 범위 병합 (3행 x 3열)
|
|
239
|
-
await ws.cell(0, 0).merge(0, 3); // A1:D1 범위 병합 (1행 x 4열)
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
### 스타일
|
|
243
|
-
|
|
244
|
-
```typescript
|
|
245
|
-
await ws.cell(0, 0).setStyle({
|
|
246
|
-
background: "00FF0000", // 배경색 (ARGB 8자리 hex, alpha 반전)
|
|
247
|
-
border: ["left", "right", "top", "bottom"], // 테두리 위치
|
|
248
|
-
horizontalAlign: "center", // 수평 정렬: "left" | "center" | "right"
|
|
249
|
-
verticalAlign: "center", // 수직 정렬: "top" | "center" | "bottom"
|
|
250
|
-
numberFormat: "number", // 숫자 서식: "number" | "string" | "DateOnly" | "DateTime" | "Time"
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
// 스타일 ID 직접 접근
|
|
254
|
-
const styleId = await ws.cell(0, 0).getStyleId();
|
|
255
|
-
await ws.cell(0, 0).setStyleId(styleId);
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**ExcelStyleOptions:**
|
|
259
|
-
|
|
260
|
-
| 필드 | 타입 | 설명 |
|
|
261
|
-
|------|------|------|
|
|
262
|
-
| `background` | `string` | ARGB 8자리 hex (예: `"00FF0000"` = 빨강) |
|
|
263
|
-
| `border` | `ExcelBorderPosition[]` | `"left"`, `"right"`, `"top"`, `"bottom"` |
|
|
264
|
-
| `horizontalAlign` | `ExcelHorizontalAlign` | `"left"`, `"center"`, `"right"` |
|
|
265
|
-
| `verticalAlign` | `ExcelVerticalAlign` | `"top"`, `"center"`, `"bottom"` |
|
|
266
|
-
| `numberFormat` | `ExcelNumberFormat` | `"number"`, `"string"`, `"DateOnly"`, `"DateTime"`, `"Time"` |
|
|
267
|
-
|
|
268
|
-
## 열 너비
|
|
269
|
-
|
|
270
|
-
```typescript
|
|
271
|
-
await ws.col(0).setWidth(20); // A열 너비 설정
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## ExcelWrapper (Zod 스키마 기반)
|
|
275
|
-
|
|
276
|
-
Zod 스키마를 기반으로 타입 안전한 Excel 읽기/쓰기를 제공한다.
|
|
277
|
-
|
|
278
|
-
### 스키마 정의
|
|
279
|
-
|
|
280
|
-
```typescript
|
|
281
|
-
import { ExcelWrapper } from "@simplysm/excel";
|
|
282
51
|
import { z } from "zod";
|
|
283
52
|
|
|
284
53
|
const schema = z.object({
|
|
285
|
-
name: z.string().describe("
|
|
286
|
-
age: z.number().describe("
|
|
287
|
-
email: z.string().optional().describe("이메일"), // optional: 필수 아닌 필드
|
|
288
|
-
active: z.boolean().describe("활성"), // boolean: 기본값 false
|
|
54
|
+
name: z.string().describe("Name"),
|
|
55
|
+
age: z.number().describe("Age"),
|
|
289
56
|
});
|
|
290
57
|
|
|
291
58
|
const wrapper = new ExcelWrapper(schema);
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
- `.describe("헤더이름")`: Excel 헤더에 표시될 이름 지정 (미지정 시 필드 키 사용)
|
|
295
|
-
- `z.optional()` / `z.nullable()` / `z.default()`: 선택 필드 (헤더 강조 없음)
|
|
296
|
-
- 필수 필드(boolean 제외)는 `write()` 시 헤더가 노란색으로 강조됨
|
|
297
|
-
|
|
298
|
-
### 읽기
|
|
299
|
-
|
|
300
|
-
```typescript
|
|
301
|
-
const records = await wrapper.read(fileBytes, "Sheet1");
|
|
302
|
-
// z.infer<typeof schema>[] 타입으로 반환
|
|
303
|
-
|
|
304
|
-
// 인덱스로 시트 지정 (기본: 0)
|
|
305
|
-
const records = await wrapper.read(fileBytes, 0);
|
|
306
|
-
|
|
307
|
-
// 특정 필드 제외
|
|
308
|
-
const records = await wrapper.read(fileBytes, "Sheet1", {
|
|
309
|
-
excludes: ["email"],
|
|
310
|
-
});
|
|
311
|
-
```
|
|
312
59
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
- `ZodNumber`: `parseFloat`로 변환
|
|
316
|
-
- `ZodBoolean`: `"1"`, `"true"` = true / `"0"`, `"false"` = false
|
|
317
|
-
- `DateOnly`, `DateTime`, `Time`: 그대로 전달
|
|
318
|
-
- 빈 값: `ZodDefault` → 기본값, `ZodOptional`/`ZodNullable` → `undefined`, `ZodBoolean` → `false`
|
|
60
|
+
// Read
|
|
61
|
+
const records = await wrapper.read(fileBytes);
|
|
319
62
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
```typescript
|
|
323
|
-
// ExcelWorkbook을 반환하므로 리소스 관리 필요
|
|
63
|
+
// Write
|
|
324
64
|
await using wb = await wrapper.write("Sheet1", [
|
|
325
|
-
{ name: "Alice", age: 30
|
|
326
|
-
{ name: "Bob", age: 25, active: false },
|
|
65
|
+
{ name: "Alice", age: 30 },
|
|
327
66
|
]);
|
|
328
67
|
const bytes = await wb.toBytes();
|
|
329
|
-
|
|
330
|
-
// 특정 필드 제외
|
|
331
|
-
await using wb = await wrapper.write("Sheet1", records, {
|
|
332
|
-
excludes: ["email"],
|
|
333
|
-
});
|
|
334
68
|
```
|
|
335
69
|
|
|
336
|
-
|
|
337
|
-
- 모든 셀에 테두리(상하좌우) 적용
|
|
338
|
-
- 필수 필드(boolean 제외) 헤더에 노란색 배경
|
|
339
|
-
- 줌 85%, 첫 행 틀고정
|
|
340
|
-
|
|
341
|
-
## 유틸리티 (ExcelUtils)
|
|
70
|
+
## Documentation
|
|
342
71
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
// 주소 변환 (0-based 좌표 <-> "A1" 형식)
|
|
347
|
-
ExcelUtils.stringifyAddr({ r: 0, c: 0 }); // "A1"
|
|
348
|
-
ExcelUtils.stringifyAddr({ r: 2, c: 1 }); // "B3"
|
|
349
|
-
ExcelUtils.stringifyColAddr(0); // "A"
|
|
350
|
-
ExcelUtils.stringifyColAddr(26); // "AA"
|
|
351
|
-
ExcelUtils.stringifyRowAddr(0); // "1"
|
|
352
|
-
|
|
353
|
-
ExcelUtils.parseCellAddr("B3"); // { r: 2, c: 1 }
|
|
354
|
-
ExcelUtils.parseColAddr("B3"); // 1
|
|
355
|
-
ExcelUtils.parseRowAddr("B3"); // 2
|
|
356
|
-
|
|
357
|
-
// 범위 주소 변환
|
|
358
|
-
ExcelUtils.parseRangeAddr("A1:C5"); // { s: {r:0,c:0}, e: {r:4,c:2} }
|
|
359
|
-
ExcelUtils.stringifyRangeAddr({ s: {r:0,c:0}, e: {r:4,c:2} }); // "A1:C5"
|
|
360
|
-
|
|
361
|
-
// 날짜 변환 (JavaScript tick <-> Excel 날짜 숫자)
|
|
362
|
-
ExcelUtils.convertTimeTickToNumber(Date.now()); // Excel 날짜 숫자
|
|
363
|
-
ExcelUtils.convertNumberToTimeTick(45678); // JavaScript timestamp (ms)
|
|
364
|
-
|
|
365
|
-
// 숫자 서식 변환
|
|
366
|
-
ExcelUtils.convertNumFmtNameToId("DateOnly"); // 14
|
|
367
|
-
ExcelUtils.convertNumFmtIdToName(14); // "DateOnly"
|
|
368
|
-
ExcelUtils.convertNumFmtCodeToName("yyyy-mm-dd"); // "DateOnly"
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
## 타입
|
|
372
|
-
|
|
373
|
-
```typescript
|
|
374
|
-
// 셀 값 타입
|
|
375
|
-
type ExcelValueType = number | string | DateOnly | DateTime | Time | boolean | undefined;
|
|
376
|
-
|
|
377
|
-
// 숫자 서식
|
|
378
|
-
type ExcelNumberFormat = "number" | "string" | "DateOnly" | "DateTime" | "Time";
|
|
379
|
-
|
|
380
|
-
// 좌표
|
|
381
|
-
interface ExcelAddressPoint { r: number; c: number; }
|
|
382
|
-
interface ExcelAddressRangePoint { s: ExcelAddressPoint; e: ExcelAddressPoint; }
|
|
383
|
-
|
|
384
|
-
// 스타일
|
|
385
|
-
type ExcelBorderPosition = "left" | "right" | "top" | "bottom";
|
|
386
|
-
type ExcelHorizontalAlign = "center" | "left" | "right";
|
|
387
|
-
type ExcelVerticalAlign = "center" | "top" | "bottom";
|
|
388
|
-
interface ExcelStyleOptions {
|
|
389
|
-
background?: string;
|
|
390
|
-
border?: ExcelBorderPosition[];
|
|
391
|
-
horizontalAlign?: ExcelHorizontalAlign;
|
|
392
|
-
verticalAlign?: ExcelVerticalAlign;
|
|
393
|
-
numberFormat?: ExcelNumberFormat;
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
// 셀 타입
|
|
397
|
-
type ExcelCellType = "s" | "b" | "str" | "n" | "inlineStr" | "e";
|
|
398
|
-
// s: SharedString, b: boolean, str: 수식 결과 문자열,
|
|
399
|
-
// n: 숫자, inlineStr: 인라인 문자열, e: 에러
|
|
400
|
-
```
|
|
72
|
+
- [Types](docs/types.md)
|
|
73
|
+
- [Core Classes](docs/core-classes.md)
|
|
74
|
+
- [Wrapper](docs/wrapper.md)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/excel",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.98",
|
|
4
4
|
"description": "Excel file processing library",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -21,6 +21,6 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"mime": "^4.1.0",
|
|
23
23
|
"zod": "^4.3.6",
|
|
24
|
-
"@simplysm/core-common": "13.0.
|
|
24
|
+
"@simplysm/core-common": "13.0.98"
|
|
25
25
|
}
|
|
26
26
|
}
|