@simplysm/excel 13.0.100 → 14.0.1
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/dist/excel-cell.d.ts +28 -28
- package/dist/excel-cell.d.ts.map +1 -1
- package/dist/excel-cell.js +273 -264
- package/dist/excel-cell.js.map +1 -6
- package/dist/excel-col.d.ts +4 -4
- package/dist/excel-col.d.ts.map +1 -1
- package/dist/excel-col.js +33 -35
- package/dist/excel-col.js.map +1 -6
- package/dist/excel-row.d.ts +3 -3
- package/dist/excel-row.d.ts.map +1 -1
- package/dist/excel-row.js +28 -30
- package/dist/excel-row.js.map +1 -6
- package/dist/excel-workbook.d.ts +23 -23
- package/dist/excel-workbook.d.ts.map +1 -1
- package/dist/excel-workbook.js +151 -125
- package/dist/excel-workbook.js.map +1 -6
- package/dist/excel-worksheet.d.ts +32 -32
- package/dist/excel-worksheet.d.ts.map +1 -1
- package/dist/excel-worksheet.js +281 -253
- package/dist/excel-worksheet.js.map +1 -6
- package/dist/excel-wrapper.d.ts +7 -7
- package/dist/excel-wrapper.d.ts.map +1 -1
- package/dist/excel-wrapper.js +190 -226
- package/dist/excel-wrapper.js.map +1 -6
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -6
- package/dist/types.d.ts +13 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -1
- package/dist/types.js.map +1 -6
- package/dist/utils/excel-utils.d.ts +23 -23
- package/dist/utils/excel-utils.d.ts.map +1 -1
- package/dist/utils/excel-utils.js +183 -151
- package/dist/utils/excel-utils.js.map +1 -6
- package/dist/utils/zip-cache.d.ts +6 -6
- package/dist/utils/zip-cache.js +78 -60
- package/dist/utils/zip-cache.js.map +1 -6
- package/dist/xml/excel-xml-content-type.d.ts +2 -2
- package/dist/xml/excel-xml-content-type.js +55 -53
- package/dist/xml/excel-xml-content-type.js.map +1 -6
- package/dist/xml/excel-xml-drawing.d.ts +2 -2
- package/dist/xml/excel-xml-drawing.js +74 -73
- package/dist/xml/excel-xml-drawing.js.map +1 -6
- package/dist/xml/excel-xml-relationship.d.ts +2 -2
- package/dist/xml/excel-xml-relationship.js +67 -67
- package/dist/xml/excel-xml-relationship.js.map +1 -6
- package/dist/xml/excel-xml-shared-string.d.ts +2 -2
- package/dist/xml/excel-xml-shared-string.js +57 -55
- package/dist/xml/excel-xml-shared-string.js.map +1 -6
- package/dist/xml/excel-xml-style.d.ts +2 -2
- package/dist/xml/excel-xml-style.js +311 -295
- package/dist/xml/excel-xml-style.js.map +1 -6
- package/dist/xml/excel-xml-unknown.d.ts +2 -2
- package/dist/xml/excel-xml-unknown.js +11 -10
- package/dist/xml/excel-xml-unknown.js.map +1 -6
- package/dist/xml/excel-xml-workbook.d.ts +2 -2
- package/dist/xml/excel-xml-workbook.js +87 -90
- package/dist/xml/excel-xml-workbook.js.map +1 -6
- package/dist/xml/excel-xml-worksheet.d.ts +6 -6
- package/dist/xml/excel-xml-worksheet.js +450 -393
- package/dist/xml/excel-xml-worksheet.js.map +1 -6
- package/package.json +5 -7
- package/src/excel-cell.ts +36 -36
- package/src/excel-col.ts +4 -4
- package/src/excel-row.ts +3 -3
- package/src/excel-workbook.ts +38 -38
- package/src/excel-worksheet.ts +69 -51
- package/src/excel-wrapper.ts +55 -50
- package/src/index.ts +3 -3
- package/src/types.ts +17 -17
- package/src/utils/excel-utils.ts +47 -41
- package/src/utils/zip-cache.ts +6 -6
- package/src/xml/excel-xml-content-type.ts +3 -3
- package/src/xml/excel-xml-drawing.ts +2 -2
- package/src/xml/excel-xml-relationship.ts +3 -3
- package/src/xml/excel-xml-shared-string.ts +2 -2
- package/src/xml/excel-xml-style.ts +11 -11
- package/src/xml/excel-xml-unknown.ts +2 -2
- package/src/xml/excel-xml-workbook.ts +5 -5
- package/src/xml/excel-xml-worksheet.ts +43 -43
- package/README.md +0 -119
- package/docs/core-classes.md +0 -541
- package/docs/types.md +0 -297
- package/docs/utilities.md +0 -128
- package/docs/wrapper.md +0 -100
- package/tests/excel-cell.spec.ts +0 -393
- package/tests/excel-col.spec.ts +0 -81
- package/tests/excel-row.spec.ts +0 -61
- package/tests/excel-workbook.spec.ts +0 -205
- package/tests/excel-worksheet.spec.ts +0 -469
- package/tests/excel-wrapper.spec.ts +0 -273
- package/tests/fixtures/logo.png +0 -0
- package/tests/fixtures//354/264/210/352/270/260/355/231/224.xlsx +0 -0
- package/tests/image-insert.spec.ts +0 -190
- package/tests/utils/excel-utils.spec.ts +0 -198
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
import type { ExcelAddressPoint, ExcelAddressRangePoint, ExcelNumberFormat } from "../types";
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Excel 유틸리티 함수 모음.
|
|
4
|
+
* 셀 주소 변환, 날짜/숫자 변환, 숫자 형식 처리 기능을 제공한다.
|
|
5
5
|
*/
|
|
6
6
|
export declare class ExcelUtils {
|
|
7
|
-
/**
|
|
7
|
+
/** 셀 좌표를 "A1" 형식 문자열로 변환 */
|
|
8
8
|
static stringifyAddr(point: ExcelAddressPoint): string;
|
|
9
|
-
/**
|
|
9
|
+
/** 행 인덱스(0 기반)를 행 주소 문자열로 변환 (예: 0 -> "1") */
|
|
10
10
|
static stringifyRowAddr(r: number): string;
|
|
11
|
-
/**
|
|
11
|
+
/** 열 인덱스(0 기반)를 열 주소 문자열로 변환 (예: 0 -> "A", 26 -> "AA") */
|
|
12
12
|
static stringifyColAddr(c: number): string;
|
|
13
|
-
/**
|
|
13
|
+
/** 셀 주소에서 행 인덱스 추출 (예: "A3" -> 2) */
|
|
14
14
|
static parseRowAddr(addr: string): number;
|
|
15
|
-
/**
|
|
15
|
+
/** 셀 주소에서 열 인덱스 추출 (예: "B3" -> 1) */
|
|
16
16
|
static parseColAddr(addr: string): number;
|
|
17
|
-
/**
|
|
17
|
+
/** 셀 주소를 좌표로 변환 (예: "B3" -> {r: 2, c: 1}) */
|
|
18
18
|
static parseCellAddr(addr: string): ExcelAddressPoint;
|
|
19
|
-
/**
|
|
19
|
+
/** 범위 주소를 좌표로 변환 (예: "A1:C3" -> {s: {r:0,c:0}, e: {r:2,c:2}}) */
|
|
20
20
|
static parseRangeAddr(rangeAddr: string): ExcelAddressRangePoint;
|
|
21
|
-
/**
|
|
21
|
+
/** 범위 좌표를 주소 문자열로 변환 */
|
|
22
22
|
static stringifyRangeAddr(point: ExcelAddressRangePoint): string;
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
* Excel
|
|
24
|
+
* JavaScript 타임스탬프(ms)를 Excel 날짜 숫자로 변환한다.
|
|
25
|
+
* Excel은 1900-01-01을 1로 계산한다 (1899-12-30이 날짜 0).
|
|
26
26
|
*/
|
|
27
27
|
static convertTimeTickToNumber(tick: number): number;
|
|
28
28
|
/**
|
|
29
|
-
*
|
|
30
|
-
* Excel
|
|
29
|
+
* Excel 날짜 숫자를 JavaScript 타임스탬프(ms)로 변환한다.
|
|
30
|
+
* Excel은 1900-01-01을 1로 계산한다 (1899-12-30이 날짜 0).
|
|
31
31
|
*/
|
|
32
32
|
static convertNumberToTimeTick(value: number): number;
|
|
33
|
-
/**
|
|
33
|
+
/** 숫자 형식 코드를 형식 이름으로 변환 */
|
|
34
34
|
static convertNumFmtCodeToName(numFmtCode: string): ExcelNumberFormat;
|
|
35
35
|
/**
|
|
36
|
-
*
|
|
36
|
+
* 숫자 형식 ID를 형식 이름으로 변환
|
|
37
37
|
*
|
|
38
38
|
* @remarks
|
|
39
|
-
* Excel
|
|
40
|
-
* - 0~13, 37~40, 48:
|
|
41
|
-
* - 14~17, 27~31, 34~36, 50~58:
|
|
42
|
-
* - 22:
|
|
43
|
-
* - 18~21, 32~33, 45~47:
|
|
44
|
-
* - 49:
|
|
39
|
+
* Excel 내장 형식 ID 범위:
|
|
40
|
+
* - 0~13, 37~40, 48: 숫자/일반/통화/퍼센트 형식
|
|
41
|
+
* - 14~17, 27~31, 34~36, 50~58: 날짜 형식 (로컬라이즈 포함)
|
|
42
|
+
* - 22: 날짜+시간 형식
|
|
43
|
+
* - 18~21, 32~33, 45~47: 시간 형식
|
|
44
|
+
* - 49: 텍스트 형식
|
|
45
45
|
*/
|
|
46
46
|
static convertNumFmtIdToName(numFmtId: number): ExcelNumberFormat;
|
|
47
|
-
/**
|
|
47
|
+
/** 숫자 형식 이름을 형식 ID로 변환 */
|
|
48
48
|
static convertNumFmtNameToId(numFmtName: ExcelNumberFormat): number;
|
|
49
49
|
}
|
|
50
50
|
//# sourceMappingURL=excel-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"excel-utils.d.ts","sourceRoot":"","sources":["..\\..\\src\\utils\\excel-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7F;;;GAGG;AACH,qBAAa,UAAU;IACrB,
|
|
1
|
+
{"version":3,"file":"excel-utils.d.ts","sourceRoot":"","sources":["..\\..\\src\\utils\\excel-utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7F;;;GAGG;AACH,qBAAa,UAAU;IACrB,4BAA4B;IAC5B,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM;IAMtD,8CAA8C;IAC9C,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAI1C,0DAA0D;IAC1D,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM;IAgB1C,qCAAqC;IACrC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IASzC,qCAAqC;IACrC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAYzC,6CAA6C;IAC7C,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB;IAOrD,iEAAiE;IACjE,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,sBAAsB;IAQhE,wBAAwB;IACxB,MAAM,CAAC,kBAAkB,CAAC,KAAK,EAAE,sBAAsB,GAAG,MAAM;IAWhE;;;OAGG;IACH,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQpD;;;OAGG;IACH,MAAM,CAAC,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IASrD,2BAA2B;IAC3B,MAAM,CAAC,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,iBAAiB;IA+BrE;;;;;;;;;;OAUG;IACH,MAAM,CAAC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB;IAkCjE,0BAA0B;IAC1B,MAAM,CAAC,qBAAqB,CAAC,UAAU,EAAE,iBAAiB,GAAG,MAAM;CAcpE"}
|
|
@@ -1,162 +1,194 @@
|
|
|
1
1
|
import { num } from "@simplysm/core-common";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
/** Convert column index (0-based) to column address string (e.g. 0 -> "A", 26 -> "AA") */
|
|
14
|
-
static stringifyColAddr(c) {
|
|
15
|
-
if (c < 0 || c > 16383) {
|
|
16
|
-
throw new Error(`Column index must be in range 0~16383: ${c}`);
|
|
2
|
+
/**
|
|
3
|
+
* Excel 유틸리티 함수 모음.
|
|
4
|
+
* 셀 주소 변환, 날짜/숫자 변환, 숫자 형식 처리 기능을 제공한다.
|
|
5
|
+
*/
|
|
6
|
+
export class ExcelUtils {
|
|
7
|
+
/** 셀 좌표를 "A1" 형식 문자열로 변환 */
|
|
8
|
+
static stringifyAddr(point) {
|
|
9
|
+
const rowStr = this.stringifyRowAddr(point.r);
|
|
10
|
+
const colStr = this.stringifyColAddr(point.c);
|
|
11
|
+
return `${colStr}${rowStr}`;
|
|
17
12
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
while (remained !== 0) {
|
|
22
|
-
result = String.fromCharCode(remained % 26 + 64) + result;
|
|
23
|
-
remained = Math.floor(remained / 26);
|
|
13
|
+
/** 행 인덱스(0 기반)를 행 주소 문자열로 변환 (예: 0 -> "1") */
|
|
14
|
+
static stringifyRowAddr(r) {
|
|
15
|
+
return (r + 1).toString();
|
|
24
16
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
17
|
+
/** 열 인덱스(0 기반)를 열 주소 문자열로 변환 (예: 0 -> "A", 26 -> "AA") */
|
|
18
|
+
static stringifyColAddr(c) {
|
|
19
|
+
if (c < 0 || c > 16383) {
|
|
20
|
+
throw new Error(`열 인덱스는 0~16383 범위여야 합니다: ${c}`);
|
|
21
|
+
}
|
|
22
|
+
let remained = c;
|
|
23
|
+
let result = String.fromCharCode((remained % 26) + 65);
|
|
24
|
+
remained = Math.floor(remained / 26);
|
|
25
|
+
while (remained !== 0) {
|
|
26
|
+
remained -= 1;
|
|
27
|
+
result = String.fromCharCode((remained % 26) + 65) + result;
|
|
28
|
+
remained = Math.floor(remained / 26);
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
34
31
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
for (let i = 0; i < revAddr.length; i++) {
|
|
44
|
-
const col = revAddr.charCodeAt(i) - (i === 0 ? 65 : 64);
|
|
45
|
-
result += col * 26 ** i;
|
|
32
|
+
/** 셀 주소에서 행 인덱스 추출 (예: "A3" -> 2) */
|
|
33
|
+
static parseRowAddr(addr) {
|
|
34
|
+
const rowAddrCode = /\d*$/.exec(addr)?.[0] ?? "";
|
|
35
|
+
const parsed = num.parseInt(rowAddrCode);
|
|
36
|
+
if (parsed == null) {
|
|
37
|
+
throw new Error(`잘못된 행 주소 코드: ${rowAddrCode}`);
|
|
38
|
+
}
|
|
39
|
+
return parsed - 1;
|
|
46
40
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
static parseRangeAddr(rangeAddr) {
|
|
58
|
-
const parts = rangeAddr.split(":");
|
|
59
|
-
return {
|
|
60
|
-
s: ExcelUtils.parseCellAddr(parts[0]),
|
|
61
|
-
e: ExcelUtils.parseCellAddr(parts[1] ?? parts[0])
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
/** Convert range coordinates to address string */
|
|
65
|
-
static stringifyRangeAddr(point) {
|
|
66
|
-
const sAddr = this.stringifyAddr(point.s);
|
|
67
|
-
const eAddr = this.stringifyAddr(point.e);
|
|
68
|
-
if (sAddr === eAddr) {
|
|
69
|
-
return sAddr;
|
|
70
|
-
} else {
|
|
71
|
-
return sAddr + ":" + eAddr;
|
|
41
|
+
/** 셀 주소에서 열 인덱스 추출 (예: "B3" -> 1) */
|
|
42
|
+
static parseColAddr(addr) {
|
|
43
|
+
const colAddrCode = /^[a-zA-Z]*/.exec(addr)?.[0] ?? "";
|
|
44
|
+
let result = 0;
|
|
45
|
+
const revAddr = Array.from(colAddrCode).reverse().join("");
|
|
46
|
+
for (let i = 0; i < revAddr.length; i++) {
|
|
47
|
+
const col = revAddr.charCodeAt(i) - (i === 0 ? 65 : 64);
|
|
48
|
+
result += col * 26 ** i;
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
72
51
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const currDate = new Date(tick);
|
|
80
|
-
currDate.setMinutes(currDate.getMinutes() - currDate.getTimezoneOffset());
|
|
81
|
-
const excelBaseDateNumberUtc = Date.UTC(1899, 11, 31);
|
|
82
|
-
const inputExcelDateNumberUtc = currDate.getTime() - excelBaseDateNumberUtc;
|
|
83
|
-
return inputExcelDateNumberUtc / (24 * 60 * 60 * 1e3) + 1;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Convert Excel date number to JavaScript timestamp (ms).
|
|
87
|
-
* Excel counts 1900-01-01 as 1 (1899-12-30 is date 0).
|
|
88
|
-
*/
|
|
89
|
-
static convertNumberToTimeTick(value) {
|
|
90
|
-
const excelBaseDateNumberUtc = Date.UTC(1899, 11, 31);
|
|
91
|
-
const excelDateNumberUtc = (value - 1) * 24 * 60 * 60 * 1e3;
|
|
92
|
-
const dateNumberUtc = excelBaseDateNumberUtc + excelDateNumberUtc;
|
|
93
|
-
const date = new Date(dateNumberUtc);
|
|
94
|
-
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
|
|
95
|
-
return date.getTime();
|
|
96
|
-
}
|
|
97
|
-
/** Convert number format code to format name */
|
|
98
|
-
static convertNumFmtCodeToName(numFmtCode) {
|
|
99
|
-
if (numFmtCode === "General") {
|
|
100
|
-
return "number";
|
|
52
|
+
/** 셀 주소를 좌표로 변환 (예: "B3" -> {r: 2, c: 1}) */
|
|
53
|
+
static parseCellAddr(addr) {
|
|
54
|
+
return {
|
|
55
|
+
r: ExcelUtils.parseRowAddr(addr),
|
|
56
|
+
c: ExcelUtils.parseColAddr(addr),
|
|
57
|
+
};
|
|
101
58
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return "Time";
|
|
110
|
-
} else if (/^[0.#,_;()\-\\$ @*?"E%+]*$/.test(numFmtCode.split("]").at(-1) ?? "")) {
|
|
111
|
-
return "number";
|
|
112
|
-
} else if ((numFmtCode.split("]").at(-1) ?? "").includes("#,0")) {
|
|
113
|
-
return "number";
|
|
114
|
-
} else {
|
|
115
|
-
throw new Error(`Unknown format for [numFmtCode: ${numFmtCode}].`);
|
|
59
|
+
/** 범위 주소를 좌표로 변환 (예: "A1:C3" -> {s: {r:0,c:0}, e: {r:2,c:2}}) */
|
|
60
|
+
static parseRangeAddr(rangeAddr) {
|
|
61
|
+
const parts = rangeAddr.split(":");
|
|
62
|
+
return {
|
|
63
|
+
s: ExcelUtils.parseCellAddr(parts[0]),
|
|
64
|
+
e: ExcelUtils.parseCellAddr(parts[1] ?? parts[0]),
|
|
65
|
+
};
|
|
116
66
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
* - 49: text format
|
|
128
|
-
*/
|
|
129
|
-
static convertNumFmtIdToName(numFmtId) {
|
|
130
|
-
if (numFmtId <= 13 || numFmtId >= 37 && numFmtId <= 40 || numFmtId === 48) {
|
|
131
|
-
return "number";
|
|
132
|
-
} else if (numFmtId >= 14 && numFmtId <= 17 || numFmtId >= 27 && numFmtId <= 31 || numFmtId >= 34 && numFmtId <= 36 || numFmtId >= 50 && numFmtId <= 58) {
|
|
133
|
-
return "DateOnly";
|
|
134
|
-
} else if (numFmtId === 22) {
|
|
135
|
-
return "DateTime";
|
|
136
|
-
} else if (numFmtId >= 18 && numFmtId <= 21 || numFmtId >= 32 && numFmtId <= 33 || numFmtId >= 45 && numFmtId <= 47) {
|
|
137
|
-
return "Time";
|
|
138
|
-
} else if (numFmtId === 49) {
|
|
139
|
-
return "string";
|
|
140
|
-
} else {
|
|
141
|
-
throw new Error(`Unknown format for [numFmtId: ${numFmtId}].`);
|
|
67
|
+
/** 범위 좌표를 주소 문자열로 변환 */
|
|
68
|
+
static stringifyRangeAddr(point) {
|
|
69
|
+
const sAddr = this.stringifyAddr(point.s);
|
|
70
|
+
const eAddr = this.stringifyAddr(point.e);
|
|
71
|
+
if (sAddr === eAddr) {
|
|
72
|
+
return sAddr;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
return sAddr + ":" + eAddr;
|
|
76
|
+
}
|
|
142
77
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
78
|
+
/**
|
|
79
|
+
* JavaScript 타임스탬프(ms)를 Excel 날짜 숫자로 변환한다.
|
|
80
|
+
* Excel은 1900-01-01을 1로 계산한다 (1899-12-30이 날짜 0).
|
|
81
|
+
*/
|
|
82
|
+
static convertTimeTickToNumber(tick) {
|
|
83
|
+
const currDate = new Date(tick);
|
|
84
|
+
currDate.setMinutes(currDate.getMinutes() - currDate.getTimezoneOffset());
|
|
85
|
+
const excelBaseDateNumberUtc = Date.UTC(1899, 11, 31);
|
|
86
|
+
const inputExcelDateNumberUtc = currDate.getTime() - excelBaseDateNumberUtc;
|
|
87
|
+
return inputExcelDateNumberUtc / (24 * 60 * 60 * 1000) + 1;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Excel 날짜 숫자를 JavaScript 타임스탬프(ms)로 변환한다.
|
|
91
|
+
* Excel은 1900-01-01을 1로 계산한다 (1899-12-30이 날짜 0).
|
|
92
|
+
*/
|
|
93
|
+
static convertNumberToTimeTick(value) {
|
|
94
|
+
const excelBaseDateNumberUtc = Date.UTC(1899, 11, 31);
|
|
95
|
+
const excelDateNumberUtc = (value - 1) * 24 * 60 * 60 * 1000;
|
|
96
|
+
const dateNumberUtc = excelBaseDateNumberUtc + excelDateNumberUtc;
|
|
97
|
+
const date = new Date(dateNumberUtc);
|
|
98
|
+
date.setMinutes(date.getMinutes() + date.getTimezoneOffset());
|
|
99
|
+
return date.getTime();
|
|
100
|
+
}
|
|
101
|
+
/** 숫자 형식 코드를 형식 이름으로 변환 */
|
|
102
|
+
static convertNumFmtCodeToName(numFmtCode) {
|
|
103
|
+
if (numFmtCode === "General") {
|
|
104
|
+
return "number";
|
|
105
|
+
}
|
|
106
|
+
// "mm"이 시간 문맥(h/hh 뒤 또는 ss 앞)에서 쓰이면 분(minute)이므로 날짜 판별에서 제외
|
|
107
|
+
const codeForDateCheck = numFmtCode
|
|
108
|
+
.replace(/h{1,2}\s*:?\s*mm/gi, "")
|
|
109
|
+
.replace(/mm\s*:?\s*ss/gi, "");
|
|
110
|
+
const hasDate = /yy/i.test(numFmtCode) || /dd/i.test(numFmtCode) || /mm/i.test(codeForDateCheck);
|
|
111
|
+
const hasTime = /h{1,2}/i.test(numFmtCode) || /ss/i.test(numFmtCode);
|
|
112
|
+
if (hasDate && hasTime) {
|
|
113
|
+
return "DateTime"; // 날짜+시간 = DateTime
|
|
114
|
+
}
|
|
115
|
+
else if (hasDate) {
|
|
116
|
+
return "DateOnly"; // 날짜만 = DateOnly
|
|
117
|
+
}
|
|
118
|
+
else if (hasTime) {
|
|
119
|
+
return "Time"; // 시간만 = Time
|
|
120
|
+
}
|
|
121
|
+
// 숫자 형식 패턴: 0, #, 소수점, 천단위 구분, 음수 구분, 괄호, 통화, 공백, 지수, 퍼센트 등
|
|
122
|
+
// "[조건부 형식]실제 형식" 구조에서 실제 형식 부분만 검사 (split("]").at(-1))
|
|
123
|
+
else if (/^[0.#,_;()\-\\$ @*?"E%+]*$/.test(numFmtCode.split("]").at(-1) ?? "")) {
|
|
124
|
+
return "number";
|
|
125
|
+
}
|
|
126
|
+
else if ((numFmtCode.split("]").at(-1) ?? "").includes("#,0")) {
|
|
127
|
+
return "number";
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
throw new Error(`알 수 없는 형식 [numFmtCode: ${numFmtCode}]`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 숫자 형식 ID를 형식 이름으로 변환
|
|
135
|
+
*
|
|
136
|
+
* @remarks
|
|
137
|
+
* Excel 내장 형식 ID 범위:
|
|
138
|
+
* - 0~13, 37~40, 48: 숫자/일반/통화/퍼센트 형식
|
|
139
|
+
* - 14~17, 27~31, 34~36, 50~58: 날짜 형식 (로컬라이즈 포함)
|
|
140
|
+
* - 22: 날짜+시간 형식
|
|
141
|
+
* - 18~21, 32~33, 45~47: 시간 형식
|
|
142
|
+
* - 49: 텍스트 형식
|
|
143
|
+
*/
|
|
144
|
+
static convertNumFmtIdToName(numFmtId) {
|
|
145
|
+
// 숫자/일반/통화/퍼센트 형식
|
|
146
|
+
if (numFmtId <= 13 || (numFmtId >= 37 && numFmtId <= 40) || numFmtId === 48) {
|
|
147
|
+
return "number";
|
|
148
|
+
}
|
|
149
|
+
// 날짜 형식 (로컬라이즈 포함)
|
|
150
|
+
else if ((numFmtId >= 14 && numFmtId <= 17) ||
|
|
151
|
+
(numFmtId >= 27 && numFmtId <= 31) ||
|
|
152
|
+
(numFmtId >= 34 && numFmtId <= 36) ||
|
|
153
|
+
(numFmtId >= 50 && numFmtId <= 58)) {
|
|
154
|
+
return "DateOnly";
|
|
155
|
+
}
|
|
156
|
+
// 날짜+시간 형식
|
|
157
|
+
else if (numFmtId === 22) {
|
|
158
|
+
return "DateTime";
|
|
159
|
+
}
|
|
160
|
+
// 시간 형식
|
|
161
|
+
else if ((numFmtId >= 18 && numFmtId <= 21) ||
|
|
162
|
+
(numFmtId >= 32 && numFmtId <= 33) ||
|
|
163
|
+
(numFmtId >= 45 && numFmtId <= 47)) {
|
|
164
|
+
return "Time";
|
|
165
|
+
}
|
|
166
|
+
// 텍스트 형식
|
|
167
|
+
else if (numFmtId === 49) {
|
|
168
|
+
return "string";
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
throw new Error(`알 수 없는 형식 [numFmtId: ${numFmtId}]`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/** 숫자 형식 이름을 형식 ID로 변환 */
|
|
175
|
+
static convertNumFmtNameToId(numFmtName) {
|
|
176
|
+
if (numFmtName === "number") {
|
|
177
|
+
return 0;
|
|
178
|
+
}
|
|
179
|
+
else if (numFmtName === "DateOnly") {
|
|
180
|
+
return 14;
|
|
181
|
+
}
|
|
182
|
+
else if (numFmtName === "DateTime") {
|
|
183
|
+
return 22;
|
|
184
|
+
}
|
|
185
|
+
else if (numFmtName === "Time") {
|
|
186
|
+
return 18;
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
// 마지막 케이스: "string" (TypeScript가 타입 좁히기를 통해 자동 검증)
|
|
190
|
+
return 49;
|
|
191
|
+
}
|
|
156
192
|
}
|
|
157
|
-
}
|
|
158
193
|
}
|
|
159
|
-
|
|
160
|
-
ExcelUtils
|
|
161
|
-
};
|
|
162
|
-
//# sourceMappingURL=excel-utils.js.map
|
|
194
|
+
//# sourceMappingURL=excel-utils.js.map
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"sources": ["../../src/utils/excel-utils.ts"],
|
|
4
|
-
"mappings": "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",
|
|
5
|
-
"names": []
|
|
6
|
-
}
|
|
1
|
+
{"version":3,"file":"excel-utils.js","sourceRoot":"","sources":["..\\..\\src\\utils\\excel-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import type { Bytes } from "@simplysm/core-common";
|
|
2
2
|
import type { ExcelXml } from "../types";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
* XML
|
|
4
|
+
* Excel ZIP 아카이브의 파일 캐시를 관리하는 클래스.
|
|
5
|
+
* XML 파일은 ExcelXml 객체로 파싱하고, 기타 파일은 바이트 배열로 캐싱한다.
|
|
6
6
|
*
|
|
7
7
|
* @remarks
|
|
8
|
-
* ## Lazy Loading
|
|
8
|
+
* ## Lazy Loading 캐시 전략
|
|
9
9
|
*
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
10
|
+
* - 파일은 최초 접근 시에만 ZIP에서 읽고 파싱함
|
|
11
|
+
* - 이후 접근은 캐싱된 객체를 반환함
|
|
12
|
+
* - 대용량 Excel 파일에서 필요한 부분만 로드하여 메모리 효율적
|
|
13
13
|
*/
|
|
14
14
|
export declare class ZipCache {
|
|
15
15
|
private readonly _cache;
|
package/dist/utils/zip-cache.js
CHANGED
|
@@ -7,68 +7,86 @@ import { ExcelXmlStyle } from "../xml/excel-xml-style.js";
|
|
|
7
7
|
import { ExcelXmlUnknown } from "../xml/excel-xml-unknown.js";
|
|
8
8
|
import { ExcelXmlWorkbook } from "../xml/excel-xml-workbook.js";
|
|
9
9
|
import { ExcelXmlWorksheet } from "../xml/excel-xml-worksheet.js";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Excel ZIP 아카이브의 파일 캐시를 관리하는 클래스.
|
|
12
|
+
* XML 파일은 ExcelXml 객체로 파싱하고, 기타 파일은 바이트 배열로 캐싱한다.
|
|
13
|
+
*
|
|
14
|
+
* @remarks
|
|
15
|
+
* ## Lazy Loading 캐시 전략
|
|
16
|
+
*
|
|
17
|
+
* - 파일은 최초 접근 시에만 ZIP에서 읽고 파싱함
|
|
18
|
+
* - 이후 접근은 캐싱된 객체를 반환함
|
|
19
|
+
* - 대용량 Excel 파일에서 필요한 부분만 로드하여 메모리 효율적
|
|
20
|
+
*/
|
|
21
|
+
export class ZipCache {
|
|
22
|
+
_cache = new Map();
|
|
23
|
+
_zip;
|
|
24
|
+
constructor(arg) {
|
|
25
|
+
this._zip = new ZipArchive(arg);
|
|
19
26
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
async get(filePath) {
|
|
28
|
+
if (this._cache.has(filePath)) {
|
|
29
|
+
return this._cache.get(filePath);
|
|
30
|
+
}
|
|
31
|
+
const fileData = await this._zip.get(filePath);
|
|
32
|
+
if (fileData == null) {
|
|
33
|
+
this._cache.set(filePath, undefined);
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
if (filePath.endsWith(".xml") || filePath.endsWith(".rels")) {
|
|
37
|
+
const fileText = new TextDecoder().decode(fileData);
|
|
38
|
+
const xml = xmlU.parse(fileText, { stripTagPrefix: true });
|
|
39
|
+
if (filePath.endsWith(".rels")) {
|
|
40
|
+
this._cache.set(filePath, new ExcelXmlRelationship(xml));
|
|
41
|
+
}
|
|
42
|
+
else if (filePath === "[Content_Types].xml") {
|
|
43
|
+
this._cache.set(filePath, new ExcelXmlContentType(xml));
|
|
44
|
+
}
|
|
45
|
+
else if (filePath === "xl/workbook.xml") {
|
|
46
|
+
this._cache.set(filePath, new ExcelXmlWorkbook(xml));
|
|
47
|
+
}
|
|
48
|
+
else if (filePath.startsWith("xl/worksheets/sheet") && filePath.endsWith(".xml")) {
|
|
49
|
+
this._cache.set(filePath, new ExcelXmlWorksheet(xml));
|
|
50
|
+
}
|
|
51
|
+
else if (filePath.startsWith("xl/drawings/drawing") && filePath.endsWith(".xml")) {
|
|
52
|
+
this._cache.set(filePath, new ExcelXmlDrawing(xml));
|
|
53
|
+
}
|
|
54
|
+
else if (filePath === "xl/sharedStrings.xml") {
|
|
55
|
+
this._cache.set(filePath, new ExcelXmlSharedString(xml));
|
|
56
|
+
}
|
|
57
|
+
else if (filePath === "xl/styles.xml") {
|
|
58
|
+
this._cache.set(filePath, new ExcelXmlStyle(xml));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
this._cache.set(filePath, new ExcelXmlUnknown(xml));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this._cache.set(filePath, fileData);
|
|
66
|
+
}
|
|
67
|
+
return this._cache.get(filePath);
|
|
24
68
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const xml = xmlU.parse(fileText, { stripTagPrefix: true });
|
|
28
|
-
if (filePath.endsWith(".rels")) {
|
|
29
|
-
this._cache.set(filePath, new ExcelXmlRelationship(xml));
|
|
30
|
-
} else if (filePath === "[Content_Types].xml") {
|
|
31
|
-
this._cache.set(filePath, new ExcelXmlContentType(xml));
|
|
32
|
-
} else if (filePath === "xl/workbook.xml") {
|
|
33
|
-
this._cache.set(filePath, new ExcelXmlWorkbook(xml));
|
|
34
|
-
} else if (filePath.startsWith("xl/worksheets/sheet") && filePath.endsWith(".xml")) {
|
|
35
|
-
this._cache.set(filePath, new ExcelXmlWorksheet(xml));
|
|
36
|
-
} else if (filePath.startsWith("xl/drawings/drawing") && filePath.endsWith(".xml")) {
|
|
37
|
-
this._cache.set(filePath, new ExcelXmlDrawing(xml));
|
|
38
|
-
} else if (filePath === "xl/sharedStrings.xml") {
|
|
39
|
-
this._cache.set(filePath, new ExcelXmlSharedString(xml));
|
|
40
|
-
} else if (filePath === "xl/styles.xml") {
|
|
41
|
-
this._cache.set(filePath, new ExcelXmlStyle(xml));
|
|
42
|
-
} else {
|
|
43
|
-
this._cache.set(filePath, new ExcelXmlUnknown(xml));
|
|
44
|
-
}
|
|
45
|
-
} else {
|
|
46
|
-
this._cache.set(filePath, fileData);
|
|
69
|
+
set(filePath, content) {
|
|
70
|
+
this._cache.set(filePath, content);
|
|
47
71
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this._zip.
|
|
62
|
-
|
|
72
|
+
async toBytes() {
|
|
73
|
+
for (const filePath of this._cache.keys()) {
|
|
74
|
+
const content = this._cache.get(filePath);
|
|
75
|
+
if (content == null)
|
|
76
|
+
continue;
|
|
77
|
+
if ("cleanup" in content) {
|
|
78
|
+
content.cleanup();
|
|
79
|
+
this._zip.write(filePath, new TextEncoder().encode(xmlU.stringify(content.data)));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
this._zip.write(filePath, content);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return this._zip.compress();
|
|
86
|
+
}
|
|
87
|
+
async close() {
|
|
88
|
+
await this._zip.close();
|
|
89
|
+
this._cache.clear();
|
|
63
90
|
}
|
|
64
|
-
return this._zip.compress();
|
|
65
|
-
}
|
|
66
|
-
async close() {
|
|
67
|
-
await this._zip.close();
|
|
68
|
-
this._cache.clear();
|
|
69
|
-
}
|
|
70
91
|
}
|
|
71
|
-
|
|
72
|
-
ZipCache
|
|
73
|
-
};
|
|
74
|
-
//# sourceMappingURL=zip-cache.js.map
|
|
92
|
+
//# sourceMappingURL=zip-cache.js.map
|