@simplysm/excel 14.0.100 → 14.0.102
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/biff/biff-model-factory.d.ts +32 -0
- package/dist/biff/biff-model-factory.d.ts.map +1 -0
- package/dist/biff/biff-model-factory.js +88 -0
- package/dist/biff/biff-model-factory.js.map +1 -0
- package/dist/biff/biff-ptg.d.ts +14 -0
- package/dist/biff/biff-ptg.d.ts.map +1 -0
- package/dist/biff/biff-ptg.js +277 -0
- package/dist/biff/biff-ptg.js.map +1 -0
- package/dist/biff/biff-records.d.ts +163 -0
- package/dist/biff/biff-records.d.ts.map +1 -0
- package/dist/biff/biff-records.js +579 -0
- package/dist/biff/biff-records.js.map +1 -0
- package/dist/biff/biff-shared-string-model.d.ts +13 -0
- package/dist/biff/biff-shared-string-model.d.ts.map +1 -0
- package/dist/biff/biff-shared-string-model.js +41 -0
- package/dist/biff/biff-shared-string-model.js.map +1 -0
- package/dist/biff/biff-style-model.d.ts +39 -0
- package/dist/biff/biff-style-model.d.ts.map +1 -0
- package/dist/biff/biff-style-model.js +182 -0
- package/dist/biff/biff-style-model.js.map +1 -0
- package/dist/biff/biff-workbook-model.d.ts +17 -0
- package/dist/biff/biff-workbook-model.d.ts.map +1 -0
- package/dist/biff/biff-workbook-model.js +64 -0
- package/dist/biff/biff-workbook-model.js.map +1 -0
- package/dist/biff/biff-worksheet-model.d.ts +69 -0
- package/dist/biff/biff-worksheet-model.d.ts.map +1 -0
- package/dist/biff/biff-worksheet-model.js +495 -0
- package/dist/biff/biff-worksheet-model.js.map +1 -0
- package/dist/biff/biff12-codec.d.ts +149 -0
- package/dist/biff/biff12-codec.d.ts.map +1 -0
- package/dist/biff/biff12-codec.js +262 -0
- package/dist/biff/biff12-codec.js.map +1 -0
- package/dist/excel-cell.d.ts +0 -6
- package/dist/excel-cell.d.ts.map +1 -1
- package/dist/excel-cell.js +2 -24
- package/dist/excel-cell.js.map +1 -1
- package/dist/excel-col.js.map +1 -1
- package/dist/excel-row.js.map +1 -1
- package/dist/excel-workbook.d.ts +4 -21
- package/dist/excel-workbook.d.ts.map +1 -1
- package/dist/excel-workbook.js +16 -49
- package/dist/excel-workbook.js.map +1 -1
- package/dist/excel-worksheet.d.ts +0 -11
- package/dist/excel-worksheet.d.ts.map +1 -1
- package/dist/excel-worksheet.js +9 -46
- package/dist/excel-worksheet.js.map +1 -1
- package/dist/excel-wrapper.d.ts +0 -10
- package/dist/excel-wrapper.d.ts.map +1 -1
- package/dist/excel-wrapper.js +0 -10
- package/dist/excel-wrapper.js.map +1 -1
- package/dist/models/excel-format.d.ts +3 -0
- package/dist/models/excel-format.d.ts.map +1 -0
- package/dist/models/excel-format.js +2 -0
- package/dist/models/excel-format.js.map +1 -0
- package/dist/models/excel-model-factory.d.ts +33 -0
- package/dist/models/excel-model-factory.d.ts.map +1 -0
- package/dist/models/excel-model-factory.js +2 -0
- package/dist/models/excel-model-factory.js.map +1 -0
- package/dist/models/excel-model.d.ts +12 -0
- package/dist/models/excel-model.d.ts.map +1 -0
- package/dist/models/excel-model.js +2 -0
- package/dist/models/excel-model.js.map +1 -0
- package/dist/models/i-content-type-model.d.ts +7 -0
- package/dist/models/i-content-type-model.d.ts.map +1 -0
- package/dist/models/i-content-type-model.js +2 -0
- package/dist/models/i-content-type-model.js.map +1 -0
- package/dist/models/i-drawing-model.d.ts +23 -0
- package/dist/models/i-drawing-model.d.ts.map +1 -0
- package/dist/models/i-drawing-model.js +2 -0
- package/dist/models/i-drawing-model.js.map +1 -0
- package/dist/models/i-relationship-model.d.ts +16 -0
- package/dist/models/i-relationship-model.d.ts.map +1 -0
- package/dist/models/i-relationship-model.js +2 -0
- package/dist/models/i-relationship-model.js.map +1 -0
- package/dist/models/i-shared-string-model.d.ts +9 -0
- package/dist/models/i-shared-string-model.d.ts.map +1 -0
- package/dist/models/i-shared-string-model.js +2 -0
- package/dist/models/i-shared-string-model.js.map +1 -0
- package/dist/models/i-style-model.d.ts +18 -0
- package/dist/models/i-style-model.d.ts.map +1 -0
- package/dist/models/i-style-model.js +2 -0
- package/dist/models/i-style-model.js.map +1 -0
- package/dist/models/i-workbook-model.d.ts +17 -0
- package/dist/models/i-workbook-model.d.ts.map +1 -0
- package/dist/models/i-workbook-model.js +2 -0
- package/dist/models/i-workbook-model.js.map +1 -0
- package/dist/models/i-worksheet-model.d.ts +39 -0
- package/dist/models/i-worksheet-model.d.ts.map +1 -0
- package/dist/models/i-worksheet-model.js +2 -0
- package/dist/models/i-worksheet-model.js.map +1 -0
- package/dist/models/shared/excel-cf-spec.d.ts +13 -0
- package/dist/models/shared/excel-cf-spec.d.ts.map +1 -0
- package/dist/models/shared/excel-cf-spec.js +2 -0
- package/dist/models/shared/excel-cf-spec.js.map +1 -0
- package/dist/models/shared/excel-style.d.ts +24 -0
- package/dist/models/shared/excel-style.d.ts.map +1 -0
- package/dist/models/shared/excel-style.js +38 -0
- package/dist/models/shared/excel-style.js.map +1 -0
- package/dist/types.d.ts +0 -13
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utils/excel-style-data.d.ts +3 -5
- package/dist/utils/excel-style-data.d.ts.map +1 -1
- package/dist/utils/excel-style-data.js +2 -16
- package/dist/utils/excel-style-data.js.map +1 -1
- package/dist/utils/zip-cache.d.ts +46 -9
- package/dist/utils/zip-cache.d.ts.map +1 -1
- package/dist/utils/zip-cache.js +138 -52
- package/dist/utils/zip-cache.js.map +1 -1
- package/dist/xml/excel-xml-content-type.d.ts +8 -4
- package/dist/xml/excel-xml-content-type.d.ts.map +1 -1
- package/dist/xml/excel-xml-content-type.js +13 -6
- package/dist/xml/excel-xml-content-type.js.map +1 -1
- package/dist/xml/excel-xml-drawing.d.ts +8 -4
- package/dist/xml/excel-xml-drawing.d.ts.map +1 -1
- package/dist/xml/excel-xml-drawing.js +14 -7
- package/dist/xml/excel-xml-drawing.js.map +1 -1
- package/dist/xml/excel-xml-relationship.d.ts +12 -4
- package/dist/xml/excel-xml-relationship.d.ts.map +1 -1
- package/dist/xml/excel-xml-relationship.js +22 -12
- package/dist/xml/excel-xml-relationship.js.map +1 -1
- package/dist/xml/excel-xml-shared-string.d.ts +8 -4
- package/dist/xml/excel-xml-shared-string.d.ts.map +1 -1
- package/dist/xml/excel-xml-shared-string.js +16 -9
- package/dist/xml/excel-xml-shared-string.js.map +1 -1
- package/dist/xml/excel-xml-style.d.ts +11 -22
- package/dist/xml/excel-xml-style.d.ts.map +1 -1
- package/dist/xml/excel-xml-style.js +66 -92
- package/dist/xml/excel-xml-style.js.map +1 -1
- package/dist/xml/excel-xml-unknown.d.ts +6 -5
- package/dist/xml/excel-xml-unknown.d.ts.map +1 -1
- package/dist/xml/excel-xml-unknown.js +7 -4
- package/dist/xml/excel-xml-unknown.js.map +1 -1
- package/dist/xml/excel-xml-workbook.d.ts +9 -4
- package/dist/xml/excel-xml-workbook.d.ts.map +1 -1
- package/dist/xml/excel-xml-workbook.js +28 -20
- package/dist/xml/excel-xml-workbook.js.map +1 -1
- package/dist/xml/excel-xml-worksheet.d.ts +12 -7
- package/dist/xml/excel-xml-worksheet.d.ts.map +1 -1
- package/dist/xml/excel-xml-worksheet.js +65 -50
- package/dist/xml/excel-xml-worksheet.js.map +1 -1
- package/dist/xml/xml-model-factory.d.ts +25 -0
- package/dist/xml/xml-model-factory.d.ts.map +1 -0
- package/dist/xml/xml-model-factory.js +66 -0
- package/dist/xml/xml-model-factory.js.map +1 -0
- package/package.json +2 -2
- package/src/biff/biff-model-factory.ts +101 -0
- package/src/biff/biff-ptg.ts +289 -0
- package/src/biff/biff-records.ts +686 -0
- package/src/biff/biff-shared-string-model.ts +52 -0
- package/src/biff/biff-style-model.ts +219 -0
- package/src/biff/biff-workbook-model.ts +83 -0
- package/src/biff/biff-worksheet-model.ts +545 -0
- package/src/biff/biff12-codec.ts +286 -0
- package/src/excel-cell.ts +12 -46
- package/src/excel-col.ts +3 -3
- package/src/excel-row.ts +3 -3
- package/src/excel-workbook.ts +26 -69
- package/src/excel-worksheet.ts +36 -107
- package/src/excel-wrapper.ts +0 -10
- package/src/models/excel-format.ts +2 -0
- package/src/models/excel-model-factory.ts +33 -0
- package/src/models/excel-model.ts +12 -0
- package/src/models/i-content-type-model.ts +7 -0
- package/src/models/i-drawing-model.ts +13 -0
- package/src/models/i-relationship-model.ts +13 -0
- package/src/models/i-shared-string-model.ts +9 -0
- package/src/models/i-style-model.ts +18 -0
- package/src/models/i-workbook-model.ts +17 -0
- package/src/models/i-worksheet-model.ts +40 -0
- package/src/models/shared/excel-cf-spec.ts +24 -0
- package/src/models/shared/excel-style.ts +65 -0
- package/src/types.ts +0 -13
- package/src/utils/excel-style-data.ts +4 -25
- package/src/utils/zip-cache.ts +189 -58
- package/src/xml/excel-xml-content-type.ts +18 -8
- package/src/xml/excel-xml-drawing.ts +19 -9
- package/src/xml/excel-xml-relationship.ts +28 -14
- package/src/xml/excel-xml-shared-string.ts +20 -11
- package/src/xml/excel-xml-style.ts +74 -116
- package/src/xml/excel-xml-unknown.ts +8 -4
- package/src/xml/excel-xml-workbook.ts +34 -22
- package/src/xml/excel-xml-worksheet.ts +73 -53
- package/src/xml/xml-model-factory.ts +83 -0
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import type { Bytes } from "@simplysm/core-common";
|
|
1
2
|
import type {
|
|
2
3
|
ExcelAddressRangePoint,
|
|
3
4
|
ExcelCellData,
|
|
4
5
|
ExcelCellType,
|
|
5
6
|
ExcelRowData,
|
|
6
|
-
ExcelXml,
|
|
7
7
|
ExcelXmlCfRuleData,
|
|
8
8
|
ExcelXmlWorksheetData,
|
|
9
9
|
} from "../types";
|
|
10
|
+
import type { ICfRuleSpec } from "../models/shared/excel-cf-spec";
|
|
11
|
+
import type { IWorksheetModel } from "../models/i-worksheet-model";
|
|
10
12
|
import { ExcelUtils } from "../utils/excel-utils";
|
|
11
|
-
import { num, obj } from "@simplysm/core-common";
|
|
13
|
+
import { num, obj, xml as xmlU } from "@simplysm/core-common";
|
|
12
14
|
import "@simplysm/core-common";
|
|
13
15
|
|
|
14
16
|
interface RowInfo {
|
|
@@ -20,14 +22,14 @@ interface RowInfo {
|
|
|
20
22
|
* xl/worksheets/sheet*.xml 파일을 관리하는 클래스.
|
|
21
23
|
* 셀 데이터, 병합, 열 너비, 행 높이 등을 처리한다.
|
|
22
24
|
*/
|
|
23
|
-
export class ExcelXmlWorksheet implements
|
|
24
|
-
|
|
25
|
+
export class ExcelXmlWorksheet implements IWorksheetModel {
|
|
26
|
+
private readonly _data: ExcelXmlWorksheetData;
|
|
25
27
|
|
|
26
28
|
private readonly _dataMap: Map<number, RowInfo>;
|
|
27
29
|
|
|
28
30
|
constructor(data?: ExcelXmlWorksheetData) {
|
|
29
31
|
if (data == null) {
|
|
30
|
-
this.
|
|
32
|
+
this._data = {
|
|
31
33
|
worksheet: {
|
|
32
34
|
$: {
|
|
33
35
|
xmlns: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
|
@@ -43,10 +45,10 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
43
45
|
},
|
|
44
46
|
};
|
|
45
47
|
} else {
|
|
46
|
-
this.
|
|
48
|
+
this._data = data;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
|
-
this._dataMap = (this.
|
|
51
|
+
this._dataMap = (this._data.worksheet.sheetData[0].row ?? []).toMap(
|
|
50
52
|
(row) => ExcelUtils.parseRowAddr(row.$.r),
|
|
51
53
|
(row) => ({
|
|
52
54
|
data: row,
|
|
@@ -58,6 +60,11 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
58
60
|
);
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
/** @internal 테스트·디버그용 내부 트리 접근. 상위 레이어는 인터페이스만 사용. */
|
|
64
|
+
get data(): ExcelXmlWorksheetData {
|
|
65
|
+
return this._data;
|
|
66
|
+
}
|
|
67
|
+
|
|
61
68
|
get range(): ExcelAddressRangePoint {
|
|
62
69
|
let maxRow = 0;
|
|
63
70
|
let maxCol = 0;
|
|
@@ -153,7 +160,7 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
153
160
|
}
|
|
154
161
|
|
|
155
162
|
setMergeCells(startAddr: { r: number; c: number }, endAddr: { r: number; c: number }): void {
|
|
156
|
-
const mergeCells = (this.
|
|
163
|
+
const mergeCells = (this._data.worksheet.mergeCells = this._data.worksheet.mergeCells ?? [
|
|
157
164
|
{
|
|
158
165
|
$: { count: "0" },
|
|
159
166
|
mergeCell: [],
|
|
@@ -194,17 +201,17 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
194
201
|
}
|
|
195
202
|
|
|
196
203
|
getMergeCells(): { s: { r: number; c: number }; e: { r: number; c: number } }[] {
|
|
197
|
-
const mergeCells = this.
|
|
204
|
+
const mergeCells = this._data.worksheet.mergeCells;
|
|
198
205
|
if (mergeCells == null) return [];
|
|
199
206
|
return mergeCells[0].mergeCell.map((item) => ExcelUtils.parseRangeAddr(item.$.ref));
|
|
200
207
|
}
|
|
201
208
|
|
|
202
209
|
removeMergeCells(fromAddr: { r: number; c: number }, toAddr: { r: number; c: number }): void {
|
|
203
|
-
if (this.
|
|
210
|
+
if (this._data.worksheet.mergeCells == null) return;
|
|
204
211
|
|
|
205
212
|
const range = { s: fromAddr, e: toAddr };
|
|
206
213
|
|
|
207
|
-
const filteredMergeCells = this.
|
|
214
|
+
const filteredMergeCells = this._data.worksheet.mergeCells[0].mergeCell.filter((item) => {
|
|
208
215
|
const rangeAddr = ExcelUtils.parseRangeAddr(item.$.ref);
|
|
209
216
|
return !(
|
|
210
217
|
rangeAddr.s.r >= range.s.r &&
|
|
@@ -215,10 +222,10 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
215
222
|
});
|
|
216
223
|
|
|
217
224
|
if (filteredMergeCells.length === 0) {
|
|
218
|
-
delete this.
|
|
225
|
+
delete this._data.worksheet.mergeCells;
|
|
219
226
|
} else {
|
|
220
|
-
this.
|
|
221
|
-
this.
|
|
227
|
+
this._data.worksheet.mergeCells[0].mergeCell = filteredMergeCells;
|
|
228
|
+
this._data.worksheet.mergeCells[0].$.count = filteredMergeCells.length.toString();
|
|
222
229
|
}
|
|
223
230
|
}
|
|
224
231
|
|
|
@@ -226,9 +233,9 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
226
233
|
* `<conditionalFormatting>` 블록을 시트에 push.
|
|
227
234
|
* priority 는 시트 전역 카운터(기존 cfRule 의 최대 priority + 1)부터 호출 내 rules 순서대로 부여.
|
|
228
235
|
*/
|
|
229
|
-
addConditionalFormatting(sqref: string, rules: { dxfId: string; cfRule:
|
|
230
|
-
const cfList = (this.
|
|
231
|
-
this.
|
|
236
|
+
addConditionalFormatting(sqref: string, rules: { dxfId: string; cfRule: ICfRuleSpec }[]): void {
|
|
237
|
+
const cfList = (this._data.worksheet.conditionalFormatting =
|
|
238
|
+
this._data.worksheet.conditionalFormatting ?? []);
|
|
232
239
|
|
|
233
240
|
let nextPriority = 1;
|
|
234
241
|
for (const block of cfList) {
|
|
@@ -258,7 +265,7 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
258
265
|
}
|
|
259
266
|
|
|
260
267
|
shiftMergeCells(fromRow: number, delta: number): void {
|
|
261
|
-
const mergeCells = this.
|
|
268
|
+
const mergeCells = this._data.worksheet.mergeCells;
|
|
262
269
|
if (mergeCells == null) return;
|
|
263
270
|
|
|
264
271
|
for (const mergeCell of mergeCells[0].mergeCell) {
|
|
@@ -290,7 +297,7 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
290
297
|
throw new Error(`잘못된 열 인덱스: ${colIndex}`);
|
|
291
298
|
}
|
|
292
299
|
|
|
293
|
-
const cols = this.
|
|
300
|
+
const cols = this._data.worksheet.cols?.[0];
|
|
294
301
|
|
|
295
302
|
// 대상 열을 포함하는 기존 범위 찾기
|
|
296
303
|
const col = cols
|
|
@@ -357,8 +364,8 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
357
364
|
}
|
|
358
365
|
} else {
|
|
359
366
|
// 기존 범위 없음: 새 범위 생성
|
|
360
|
-
this.
|
|
361
|
-
this.
|
|
367
|
+
this._data.worksheet.cols = this._data.worksheet.cols ?? [{ col: [] }];
|
|
368
|
+
this._data.worksheet.cols[0].col.push({
|
|
362
369
|
$: {
|
|
363
370
|
min: colIndex,
|
|
364
371
|
max: colIndex,
|
|
@@ -371,24 +378,24 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
371
378
|
}
|
|
372
379
|
|
|
373
380
|
setTabColor(rgb: string): void {
|
|
374
|
-
this.
|
|
375
|
-
this.
|
|
381
|
+
this._data.worksheet.sheetPr = this._data.worksheet.sheetPr ?? [{}];
|
|
382
|
+
this._data.worksheet.sheetPr[0].tabColor = [{ $: { rgb } }];
|
|
376
383
|
}
|
|
377
384
|
|
|
378
385
|
setZoom(percent: number): void {
|
|
379
|
-
this.
|
|
386
|
+
this._data.worksheet.sheetViews = this._data.worksheet.sheetViews ?? [
|
|
380
387
|
{ sheetView: [{ $: { workbookViewId: "0" } }] },
|
|
381
388
|
];
|
|
382
389
|
|
|
383
|
-
this.
|
|
390
|
+
this._data.worksheet.sheetViews[0].sheetView[0].$.zoomScale = percent.toString();
|
|
384
391
|
}
|
|
385
392
|
|
|
386
393
|
freezeAt(point: { r?: number; c?: number }): void {
|
|
387
|
-
this.
|
|
394
|
+
this._data.worksheet.sheetViews = this._data.worksheet.sheetViews ?? [
|
|
388
395
|
{ sheetView: [{ $: { workbookViewId: "0" } }] },
|
|
389
396
|
];
|
|
390
397
|
|
|
391
|
-
this.
|
|
398
|
+
this._data.worksheet.sheetViews[0].sheetView[0].pane = [
|
|
392
399
|
{
|
|
393
400
|
$: {
|
|
394
401
|
...(point.c != null
|
|
@@ -413,7 +420,7 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
413
420
|
}
|
|
414
421
|
|
|
415
422
|
setAutoFilter(range: ExcelAddressRangePoint): void {
|
|
416
|
-
this.
|
|
423
|
+
this._data.worksheet.autoFilter = [
|
|
417
424
|
{ $: { ref: ExcelUtils.stringifyRangeAddr(range) } },
|
|
418
425
|
];
|
|
419
426
|
}
|
|
@@ -482,12 +489,25 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
482
489
|
}
|
|
483
490
|
}
|
|
484
491
|
|
|
485
|
-
|
|
492
|
+
setDrawingRelId(relId: string): void {
|
|
493
|
+
this._data.worksheet.$["xmlns:r"] =
|
|
494
|
+
this._data.worksheet.$["xmlns:r"] ??
|
|
495
|
+
"http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
496
|
+
this._data.worksheet.drawing = this._data.worksheet.drawing ?? [];
|
|
497
|
+
this._data.worksheet.drawing.push({ $: { "r:id": relId } });
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
serialize(): Bytes {
|
|
501
|
+
this._cleanup();
|
|
502
|
+
return new TextEncoder().encode(xmlU.stringify(this._data));
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
private _cleanup(): void {
|
|
486
506
|
const result = {} as ExcelXmlWorksheetData["worksheet"];
|
|
487
507
|
|
|
488
508
|
// 정렬 순서 ("sheetData" 기준, 나머지는 원래 위치 유지)
|
|
489
509
|
|
|
490
|
-
for (const key of Object.keys(this.
|
|
510
|
+
for (const key of Object.keys(this._data.worksheet)) {
|
|
491
511
|
if (key === "mergeCells") continue;
|
|
492
512
|
if (key === "cols") continue;
|
|
493
513
|
if (key === "sheetViews") continue;
|
|
@@ -499,32 +519,32 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
499
519
|
|
|
500
520
|
if (key === "sheetData") {
|
|
501
521
|
// OOXML CT_Worksheet 자식 순서: sheetPr → dimension → sheetViews → sheetFormatPr → cols → sheetData → autoFilter → mergeCells → conditionalFormatting
|
|
502
|
-
if (this.
|
|
503
|
-
result.sheetPr = this.
|
|
522
|
+
if (this._data.worksheet.sheetPr != null) {
|
|
523
|
+
result.sheetPr = this._data.worksheet.sheetPr;
|
|
504
524
|
}
|
|
505
|
-
result.dimension = this.
|
|
506
|
-
if (this.
|
|
507
|
-
result.sheetViews = this.
|
|
525
|
+
result.dimension = this._data.worksheet.dimension ?? [{ $: { ref: "A1" } }];
|
|
526
|
+
if (this._data.worksheet.sheetViews != null) {
|
|
527
|
+
result.sheetViews = this._data.worksheet.sheetViews;
|
|
508
528
|
}
|
|
509
|
-
if (this.
|
|
510
|
-
result.sheetFormatPr = this.
|
|
529
|
+
if (this._data.worksheet.sheetFormatPr != null) {
|
|
530
|
+
result.sheetFormatPr = this._data.worksheet.sheetFormatPr;
|
|
511
531
|
}
|
|
512
|
-
if (this.
|
|
513
|
-
result.cols = this.
|
|
532
|
+
if (this._data.worksheet.cols != null) {
|
|
533
|
+
result.cols = this._data.worksheet.cols;
|
|
514
534
|
}
|
|
515
|
-
result.sheetData = this.
|
|
535
|
+
result.sheetData = this._data.worksheet.sheetData;
|
|
516
536
|
|
|
517
|
-
if (this.
|
|
518
|
-
result.autoFilter = this.
|
|
537
|
+
if (this._data.worksheet.autoFilter != null) {
|
|
538
|
+
result.autoFilter = this._data.worksheet.autoFilter;
|
|
519
539
|
}
|
|
520
|
-
if (this.
|
|
521
|
-
result.mergeCells = this.
|
|
540
|
+
if (this._data.worksheet.mergeCells != null) {
|
|
541
|
+
result.mergeCells = this._data.worksheet.mergeCells;
|
|
522
542
|
}
|
|
523
|
-
if (this.
|
|
524
|
-
result.conditionalFormatting = this.
|
|
543
|
+
if (this._data.worksheet.conditionalFormatting != null) {
|
|
544
|
+
result.conditionalFormatting = this._data.worksheet.conditionalFormatting;
|
|
525
545
|
}
|
|
526
546
|
} else {
|
|
527
|
-
const worksheetRec = this.
|
|
547
|
+
const worksheetRec = this._data.worksheet as Record<string, unknown>;
|
|
528
548
|
const resultRec = result as Record<string, unknown>;
|
|
529
549
|
resultRec[key] = worksheetRec[key];
|
|
530
550
|
}
|
|
@@ -547,7 +567,7 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
547
567
|
const dimension = (result.dimension ??= [{ $: { ref: "A1" } }]);
|
|
548
568
|
dimension[0].$.ref = ExcelUtils.stringifyRangeAddr(this.range);
|
|
549
569
|
|
|
550
|
-
this.
|
|
570
|
+
this._data.worksheet = result;
|
|
551
571
|
}
|
|
552
572
|
|
|
553
573
|
private _getCellData(addr: { r: number; c: number }): ExcelCellData | undefined {
|
|
@@ -583,8 +603,8 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
583
603
|
this._deleteRow(r);
|
|
584
604
|
|
|
585
605
|
// 시트에 쓰기
|
|
586
|
-
this.
|
|
587
|
-
this.
|
|
606
|
+
this._data.worksheet.sheetData[0].row = this._data.worksheet.sheetData[0].row ?? [];
|
|
607
|
+
this._data.worksheet.sheetData[0].row.push(rowData);
|
|
588
608
|
|
|
589
609
|
// 캐시에 쓰기
|
|
590
610
|
const rowInfo = {
|
|
@@ -616,7 +636,7 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
616
636
|
private _deleteRow(r: number): void {
|
|
617
637
|
const targetRowInfo = this._dataMap.get(r);
|
|
618
638
|
if (targetRowInfo != null) {
|
|
619
|
-
const rows = this.
|
|
639
|
+
const rows = this._data.worksheet.sheetData[0].row;
|
|
620
640
|
if (rows) {
|
|
621
641
|
const rowIndex = rows.indexOf(targetRowInfo.data);
|
|
622
642
|
if (rowIndex !== -1) rows.splice(rowIndex, 1);
|
|
@@ -625,8 +645,8 @@ export class ExcelXmlWorksheet implements ExcelXml {
|
|
|
625
645
|
this._dataMap.delete(r);
|
|
626
646
|
|
|
627
647
|
// 행이 남아있지 않으면 XML에서 행 섹션 삭제
|
|
628
|
-
if (this.
|
|
629
|
-
delete this.
|
|
648
|
+
if (this._data.worksheet.sheetData[0].row?.length === 0) {
|
|
649
|
+
delete this._data.worksheet.sheetData[0].row;
|
|
630
650
|
}
|
|
631
651
|
}
|
|
632
652
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Bytes } from "@simplysm/core-common";
|
|
2
|
+
import { xml as xmlU } from "@simplysm/core-common";
|
|
3
|
+
import type { ExcelFormat } from "../models/excel-format";
|
|
4
|
+
import type { IExcelModel } from "../models/excel-model";
|
|
5
|
+
import type { IExcelModelFactory } from "../models/excel-model-factory";
|
|
6
|
+
import type { IContentTypeModel } from "../models/i-content-type-model";
|
|
7
|
+
import type { IDrawingModel } from "../models/i-drawing-model";
|
|
8
|
+
import type { IRelationshipModel } from "../models/i-relationship-model";
|
|
9
|
+
import type { ISharedStringModel } from "../models/i-shared-string-model";
|
|
10
|
+
import type { IStyleModel } from "../models/i-style-model";
|
|
11
|
+
import type { IWorkbookModel } from "../models/i-workbook-model";
|
|
12
|
+
import type { IWorksheetModel } from "../models/i-worksheet-model";
|
|
13
|
+
import type {
|
|
14
|
+
ExcelXmlContentTypeData,
|
|
15
|
+
ExcelXmlDrawingData,
|
|
16
|
+
ExcelXmlRelationshipData,
|
|
17
|
+
ExcelXmlSharedStringData,
|
|
18
|
+
ExcelXmlStyleData,
|
|
19
|
+
ExcelXmlWorkbookData,
|
|
20
|
+
ExcelXmlWorksheetData,
|
|
21
|
+
} from "../types";
|
|
22
|
+
import { ExcelXmlContentType } from "./excel-xml-content-type";
|
|
23
|
+
import { ExcelXmlDrawing } from "./excel-xml-drawing";
|
|
24
|
+
import { ExcelXmlRelationship } from "./excel-xml-relationship";
|
|
25
|
+
import { ExcelXmlSharedString } from "./excel-xml-shared-string";
|
|
26
|
+
import { ExcelXmlStyle } from "./excel-xml-style";
|
|
27
|
+
import { ExcelXmlUnknown } from "./excel-xml-unknown";
|
|
28
|
+
import { ExcelXmlWorkbook } from "./excel-xml-workbook";
|
|
29
|
+
import { ExcelXmlWorksheet } from "./excel-xml-worksheet";
|
|
30
|
+
|
|
31
|
+
/** xlsx(OOXML XML) 포맷의 파트 모델 팩토리. */
|
|
32
|
+
export class XmlModelFactory implements IExcelModelFactory {
|
|
33
|
+
readonly format: ExcelFormat = "xlsx";
|
|
34
|
+
|
|
35
|
+
isModelPart(filePath: string): boolean {
|
|
36
|
+
return filePath.endsWith(".xml") || filePath.endsWith(".rels");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
createWorkbook(): IWorkbookModel {
|
|
40
|
+
return new ExcelXmlWorkbook();
|
|
41
|
+
}
|
|
42
|
+
createWorksheet(): IWorksheetModel {
|
|
43
|
+
return new ExcelXmlWorksheet();
|
|
44
|
+
}
|
|
45
|
+
createStyle(): IStyleModel {
|
|
46
|
+
return new ExcelXmlStyle();
|
|
47
|
+
}
|
|
48
|
+
createSharedString(): ISharedStringModel {
|
|
49
|
+
return new ExcelXmlSharedString();
|
|
50
|
+
}
|
|
51
|
+
createContentType(): IContentTypeModel {
|
|
52
|
+
return new ExcelXmlContentType();
|
|
53
|
+
}
|
|
54
|
+
createRelationship(): IRelationshipModel {
|
|
55
|
+
return new ExcelXmlRelationship();
|
|
56
|
+
}
|
|
57
|
+
createDrawing(): IDrawingModel {
|
|
58
|
+
return new ExcelXmlDrawing();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
parse(filePath: string, bytes: Bytes): IExcelModel {
|
|
62
|
+
const fileText = new TextDecoder().decode(bytes);
|
|
63
|
+
const xml = xmlU.parse(fileText, { stripTagPrefix: true });
|
|
64
|
+
|
|
65
|
+
if (filePath.endsWith(".rels")) {
|
|
66
|
+
return new ExcelXmlRelationship(xml as ExcelXmlRelationshipData);
|
|
67
|
+
} else if (filePath === "[Content_Types].xml") {
|
|
68
|
+
return new ExcelXmlContentType(xml as ExcelXmlContentTypeData);
|
|
69
|
+
} else if (filePath === "xl/workbook.xml") {
|
|
70
|
+
return new ExcelXmlWorkbook(xml as ExcelXmlWorkbookData);
|
|
71
|
+
} else if (filePath.startsWith("xl/worksheets/sheet") && filePath.endsWith(".xml")) {
|
|
72
|
+
return new ExcelXmlWorksheet(xml as ExcelXmlWorksheetData);
|
|
73
|
+
} else if (filePath.startsWith("xl/drawings/drawing") && filePath.endsWith(".xml")) {
|
|
74
|
+
return new ExcelXmlDrawing(xml as ExcelXmlDrawingData);
|
|
75
|
+
} else if (filePath === "xl/sharedStrings.xml") {
|
|
76
|
+
return new ExcelXmlSharedString(xml as ExcelXmlSharedStringData);
|
|
77
|
+
} else if (filePath === "xl/styles.xml") {
|
|
78
|
+
return new ExcelXmlStyle(xml as ExcelXmlStyleData);
|
|
79
|
+
} else {
|
|
80
|
+
return new ExcelXmlUnknown(xml as Record<string, unknown>);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|