@iyulab/flex-table 0.43.0 → 0.44.0
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/CHANGELOG.md +15 -0
- package/README.md +3 -2
- package/dist/export/export.d.ts +6 -1
- package/dist/export/xlsx-deflate.test.d.ts +1 -0
- package/dist/export/xlsx-writer.d.ts +8 -1
- package/dist/{flex-table-BdnkC234.js → flex-table-MnSI0Ogl.js} +145 -84
- package/dist/flex-table.d.ts +14 -3
- package/dist/flex-table.js +1 -1
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/skills/iyulab-flex-table/references/api.md +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.44.0] - 2026-10-05
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`exportToBlob(format, options?)`** — the export as a `Blob` typed with the format's MIME type.
|
|
8
|
+
XLSX comes out DEFLATE-compressed (platform `CompressionStream`), a fraction of the stored size —
|
|
9
|
+
a 500-row sheet is under a quarter of it.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **`exportToFile` returns `Promise<void>` and downloads a compressed XLSX.** It was synchronous and
|
|
14
|
+
wrote the workbook uncompressed (ZIP STORE). Calling it without `await` still works.
|
|
15
|
+
`exportToString` stays synchronous and still returns an uncompressed workbook for `'xlsx'` — use
|
|
16
|
+
`exportToBlob` when the bytes leave the browser.
|
|
17
|
+
|
|
3
18
|
## [0.43.0] - 2026-10-04
|
|
4
19
|
|
|
5
20
|
### Changed
|
package/README.md
CHANGED
|
@@ -276,8 +276,9 @@ Default is `false`, matching `clear-undo-on-data-change`.
|
|
|
276
276
|
|
|
277
277
|
| Method | Returns | Description |
|
|
278
278
|
|--------|---------|-------------|
|
|
279
|
-
| `exportToString(format, options?)` | `string \| Uint8Array` | Export to `'csv'` / `'tsv'` / `'json'` (a string) or `'xlsx'` (bytes). Pass `{ selectionOnly: true }` for selection range |
|
|
280
|
-
| `
|
|
279
|
+
| `exportToString(format, options?)` | `string \| Uint8Array` | Export to `'csv'` / `'tsv'` / `'json'` (a string) or `'xlsx'` (bytes, uncompressed). Pass `{ selectionOnly: true }` for selection range |
|
|
280
|
+
| `exportToBlob(format, options?)` | `Promise<Blob>` | The same export as a `Blob` of the format's MIME type — `'xlsx'` is DEFLATE-compressed |
|
|
281
|
+
| `exportToFile(format, filename?)` | `Promise<void>` | Export and trigger browser file download (`'xlsx'` compressed) |
|
|
281
282
|
|
|
282
283
|
## Events
|
|
283
284
|
|
package/dist/export/export.d.ts
CHANGED
|
@@ -5,9 +5,14 @@ export type ExportFormat = 'csv' | 'tsv' | 'json' | 'xlsx';
|
|
|
5
5
|
* Returns string for text formats (csv/tsv/json) or Uint8Array for xlsx.
|
|
6
6
|
*/
|
|
7
7
|
export declare function exportData(data: DataRow[], columns: ColumnDefinition[], format: ExportFormat): string | Uint8Array<ArrayBuffer>;
|
|
8
|
+
/**
|
|
9
|
+
* Export data as a `Blob` of the format's MIME type. XLSX is DEFLATE-compressed (unlike `exportData`,
|
|
10
|
+
* which stays synchronous and therefore stores the workbook uncompressed).
|
|
11
|
+
*/
|
|
12
|
+
export declare function exportDataBlob(data: DataRow[], columns: ColumnDefinition[], format: ExportFormat): Promise<Blob>;
|
|
8
13
|
/**
|
|
9
14
|
* Trigger a file download in the browser.
|
|
10
15
|
*/
|
|
11
|
-
export declare function
|
|
16
|
+
export declare function downloadBlob(blob: Blob, filename: string): void;
|
|
12
17
|
export declare function getExportMimeType(format: ExportFormat): string;
|
|
13
18
|
export declare function getExportExtension(format: ExportFormat): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Minimal XLSX writer — no external dependencies.
|
|
3
|
-
* Generates OOXML (.xlsx) files
|
|
3
|
+
* Generates OOXML (.xlsx) files — ZIP STORE (sync) or DEFLATE (async, platform CompressionStream).
|
|
4
4
|
* Supports string, number, boolean, and date cell types.
|
|
5
5
|
*/
|
|
6
6
|
import type { ColumnDefinition, DataRow } from '../models/types.js';
|
|
@@ -10,7 +10,14 @@ export interface ZipFile {
|
|
|
10
10
|
}
|
|
11
11
|
/** @internal 테스트가 실물에 가까운 통합 문서(스타일·1904 날짜 체계)를 조립하는 데 쓴다. */
|
|
12
12
|
export declare function buildZip(files: ZipFile[]): Uint8Array<ArrayBuffer>;
|
|
13
|
+
/**
|
|
14
|
+
* DEFLATE 로 압축한 ZIP. 항목마다 압축본이 원본보다 작을 때만 DEFLATE 를 쓰고, 아니면 STORE 로 둔다.
|
|
15
|
+
* 압축은 플랫폼 `CompressionStream('deflate-raw')` 라 비동기다 — 읽기 쪽이 이미 `DecompressionStream` 을 쓴다.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildZipDeflated(files: ZipFile[]): Promise<Uint8Array<ArrayBuffer>>;
|
|
13
18
|
/**
|
|
14
19
|
* Build an XLSX file as a Uint8Array.
|
|
15
20
|
*/
|
|
16
21
|
export declare function buildXlsx(data: DataRow[], columns: ColumnDefinition[]): Uint8Array<ArrayBuffer>;
|
|
22
|
+
/** Build a DEFLATE-compressed XLSX file — the same workbook as `buildXlsx`, a fraction of the size. */
|
|
23
|
+
export declare function buildXlsxDeflated(data: DataRow[], columns: ColumnDefinition[]): Promise<Uint8Array<ArrayBuffer>>;
|
|
@@ -1442,49 +1442,83 @@ function de(e) {
|
|
|
1442
1442
|
}
|
|
1443
1443
|
var F = new TextEncoder();
|
|
1444
1444
|
function fe(e) {
|
|
1445
|
+
return I(e.map((e) => ({
|
|
1446
|
+
...e,
|
|
1447
|
+
body: e.data,
|
|
1448
|
+
method: 0
|
|
1449
|
+
})));
|
|
1450
|
+
}
|
|
1451
|
+
async function pe(e) {
|
|
1452
|
+
let t = [];
|
|
1453
|
+
for (let n of e) {
|
|
1454
|
+
let e = await me(n.data);
|
|
1455
|
+
t.push(e.length < n.data.length ? {
|
|
1456
|
+
...n,
|
|
1457
|
+
body: e,
|
|
1458
|
+
method: 8
|
|
1459
|
+
} : {
|
|
1460
|
+
...n,
|
|
1461
|
+
body: n.data,
|
|
1462
|
+
method: 0
|
|
1463
|
+
});
|
|
1464
|
+
}
|
|
1465
|
+
return I(t);
|
|
1466
|
+
}
|
|
1467
|
+
async function me(e) {
|
|
1468
|
+
let t = new CompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
|
|
1469
|
+
n.write(e), n.close();
|
|
1470
|
+
let i = [];
|
|
1471
|
+
for (;;) {
|
|
1472
|
+
let { done: e, value: t } = await r.read();
|
|
1473
|
+
if (e) break;
|
|
1474
|
+
i.push(t);
|
|
1475
|
+
}
|
|
1476
|
+
return L(i);
|
|
1477
|
+
}
|
|
1478
|
+
function I(e) {
|
|
1445
1479
|
let t = [], n = [], r = 0;
|
|
1446
1480
|
for (let i of e) {
|
|
1447
|
-
let e = F.encode(i.name), a = de(i.data), o = i.data.length, s = new ArrayBuffer(30 + e.length),
|
|
1448
|
-
|
|
1449
|
-
let
|
|
1450
|
-
|
|
1481
|
+
let e = F.encode(i.name), a = de(i.data), o = i.data.length, s = i.body.length, c = i.method === 8 ? 20 : 10, l = new ArrayBuffer(30 + e.length), u = new DataView(l);
|
|
1482
|
+
u.setUint32(0, 67324752, !0), u.setUint16(4, c, !0), u.setUint16(6, 0, !0), u.setUint16(8, i.method, !0), u.setUint16(10, 0, !0), u.setUint16(12, 33, !0), u.setUint32(14, a, !0), u.setUint32(18, s, !0), u.setUint32(22, o, !0), u.setUint16(26, e.length, !0), u.setUint16(28, 0, !0), new Uint8Array(l, 30).set(e), t.push(new Uint8Array(l)), t.push(i.body);
|
|
1483
|
+
let d = new ArrayBuffer(46 + e.length), f = new DataView(d);
|
|
1484
|
+
f.setUint32(0, 33639248, !0), f.setUint16(4, 20, !0), f.setUint16(6, c, !0), f.setUint16(8, 0, !0), f.setUint16(10, i.method, !0), f.setUint16(12, 0, !0), f.setUint16(14, 33, !0), f.setUint32(16, a, !0), f.setUint32(20, s, !0), f.setUint32(24, o, !0), f.setUint16(28, e.length, !0), f.setUint16(30, 0, !0), f.setUint16(32, 0, !0), f.setUint16(34, 0, !0), f.setUint16(36, 0, !0), f.setUint32(38, 0, !0), f.setUint32(42, r, !0), new Uint8Array(d, 46).set(e), n.push(new Uint8Array(d)), r += 30 + e.length + s;
|
|
1451
1485
|
}
|
|
1452
|
-
let i =
|
|
1453
|
-
return o.setUint32(0, 101010256, !0), o.setUint16(4, 0, !0), o.setUint16(6, 0, !0), o.setUint16(8, e.length, !0), o.setUint16(10, e.length, !0), o.setUint32(12, i.length, !0), o.setUint32(16, r, !0), o.setUint16(20, 0, !0),
|
|
1486
|
+
let i = L(n), a = /* @__PURE__ */ new ArrayBuffer(22), o = new DataView(a);
|
|
1487
|
+
return o.setUint32(0, 101010256, !0), o.setUint16(4, 0, !0), o.setUint16(6, 0, !0), o.setUint16(8, e.length, !0), o.setUint16(10, e.length, !0), o.setUint32(12, i.length, !0), o.setUint32(16, r, !0), o.setUint16(20, 0, !0), L([
|
|
1454
1488
|
...t,
|
|
1455
1489
|
i,
|
|
1456
1490
|
new Uint8Array(a)
|
|
1457
1491
|
]);
|
|
1458
1492
|
}
|
|
1459
|
-
function
|
|
1493
|
+
function L(e) {
|
|
1460
1494
|
let t = e.reduce((e, t) => e + t.length, 0), n = new Uint8Array(t), r = 0;
|
|
1461
1495
|
for (let t of e) n.set(t, r), r += t.length;
|
|
1462
1496
|
return n;
|
|
1463
1497
|
}
|
|
1464
|
-
function
|
|
1498
|
+
function R(e) {
|
|
1465
1499
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1466
1500
|
}
|
|
1467
|
-
function
|
|
1501
|
+
function he(e) {
|
|
1468
1502
|
let t = "";
|
|
1469
1503
|
for (e++; e > 0;) t = String.fromCharCode(64 + (e % 26 || 26)) + t, e = Math.floor((e - 1) / 26);
|
|
1470
1504
|
return t;
|
|
1471
1505
|
}
|
|
1472
|
-
function
|
|
1473
|
-
return
|
|
1506
|
+
function z(e, t) {
|
|
1507
|
+
return he(t) + (e + 1);
|
|
1474
1508
|
}
|
|
1475
|
-
function
|
|
1509
|
+
function ge(e) {
|
|
1476
1510
|
let t = Date.UTC(1899, 11, 30);
|
|
1477
1511
|
return (e.getTime() - t) / 864e5;
|
|
1478
1512
|
}
|
|
1479
|
-
var
|
|
1480
|
-
function
|
|
1481
|
-
let n = [], r = t.map((e, t) => `<c r="${
|
|
1513
|
+
var _e = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">\n <Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\"/>\n <Default Extension=\"xml\" ContentType=\"application/xml\"/>\n <Override PartName=\"/xl/workbook.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml\"/>\n <Override PartName=\"/xl/worksheets/sheet1.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml\"/>\n <Override PartName=\"/xl/styles.xml\" ContentType=\"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml\"/>\n</Types>", ve = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\" Target=\"xl/workbook.xml\"/>\n</Relationships>", ye = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<workbook xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\">\n <sheets><sheet name=\"Sheet1\" sheetId=\"1\" r:id=\"rId1\"/></sheets>\n</workbook>", be = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">\n <Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\" Target=\"worksheets/sheet1.xml\"/>\n <Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles\" Target=\"styles.xml\"/>\n</Relationships>", xe = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<styleSheet xmlns=\"http://schemas.openxmlformats.org/spreadsheetml/2006/main\">\n <numFmts count=\"1\"><numFmt numFmtId=\"164\" formatCode=\"yyyy-mm-dd\"/></numFmts>\n <fonts count=\"2\">\n <font><sz val=\"11\"/><name val=\"Calibri\"/></font>\n <font><sz val=\"11\"/><b/><name val=\"Calibri\"/></font>\n </fonts>\n <fills count=\"2\">\n <fill><patternFill patternType=\"none\"/></fill>\n <fill><patternFill patternType=\"gray125\"/></fill>\n </fills>\n <borders count=\"1\"><border><left/><right/><top/><bottom/><diagonal/></border></borders>\n <cellStyleXfs count=\"1\"><xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\"/></cellStyleXfs>\n <cellXfs count=\"3\">\n <xf numFmtId=\"0\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\"/>\n <xf numFmtId=\"164\" fontId=\"0\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyNumberFormat=\"1\"/>\n <xf numFmtId=\"0\" fontId=\"1\" fillId=\"0\" borderId=\"0\" xfId=\"0\" applyFont=\"1\"/>\n </cellXfs>\n</styleSheet>";
|
|
1514
|
+
function Se(e, t) {
|
|
1515
|
+
let n = [], r = t.map((e, t) => `<c r="${z(0, t)}" t="str" s="2"><v>${R(e.label)}</v></c>`);
|
|
1482
1516
|
return n.push(`<row r="1">${r.join("")}</row>`), e.forEach((e, r) => {
|
|
1483
1517
|
let i = t.map((t, n) => {
|
|
1484
|
-
let i =
|
|
1518
|
+
let i = z(r + 1, n), a = e[t.key];
|
|
1485
1519
|
if (a == null) return `<c r="${i}" t="str"><v></v></c>`;
|
|
1486
1520
|
let o = t.type ?? "text";
|
|
1487
|
-
return o === "number" && typeof a == "number" ? `<c r="${i}"><v>${a}</v></c>` : (o === "date" || o === "datetime") && a instanceof Date ? `<c r="${i}" s="1"><v>${
|
|
1521
|
+
return o === "number" && typeof a == "number" ? `<c r="${i}"><v>${a}</v></c>` : (o === "date" || o === "datetime") && a instanceof Date ? `<c r="${i}" s="1"><v>${ge(a).toFixed(6)}</v></c>` : o === "boolean" ? `<c r="${i}" t="b"><v>${+!!a}</v></c>` : `<c r="${i}" t="str"><v>${R(String(a))}</v></c>`;
|
|
1488
1522
|
});
|
|
1489
1523
|
n.push(`<row r="${r + 2}">${i.join("")}</row>`);
|
|
1490
1524
|
}), `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
@@ -1492,24 +1526,30 @@ function ye(e, t) {
|
|
|
1492
1526
|
<sheetData>${n.join("")}</sheetData>
|
|
1493
1527
|
</worksheet>`;
|
|
1494
1528
|
}
|
|
1495
|
-
function
|
|
1496
|
-
|
|
1497
|
-
|
|
1529
|
+
function Ce(e, t) {
|
|
1530
|
+
return fe(B(e, t));
|
|
1531
|
+
}
|
|
1532
|
+
function we(e, t) {
|
|
1533
|
+
return pe(B(e, t));
|
|
1534
|
+
}
|
|
1535
|
+
function B(e, t) {
|
|
1536
|
+
let n = Se(e, t);
|
|
1537
|
+
return [
|
|
1498
1538
|
{
|
|
1499
1539
|
name: "[Content_Types].xml",
|
|
1500
|
-
data: F.encode(
|
|
1540
|
+
data: F.encode(_e)
|
|
1501
1541
|
},
|
|
1502
1542
|
{
|
|
1503
1543
|
name: "_rels/.rels",
|
|
1504
|
-
data: F.encode(
|
|
1544
|
+
data: F.encode(ve)
|
|
1505
1545
|
},
|
|
1506
1546
|
{
|
|
1507
1547
|
name: "xl/workbook.xml",
|
|
1508
|
-
data: F.encode(
|
|
1548
|
+
data: F.encode(ye)
|
|
1509
1549
|
},
|
|
1510
1550
|
{
|
|
1511
1551
|
name: "xl/_rels/workbook.xml.rels",
|
|
1512
|
-
data: F.encode(
|
|
1552
|
+
data: F.encode(be)
|
|
1513
1553
|
},
|
|
1514
1554
|
{
|
|
1515
1555
|
name: "xl/worksheets/sheet1.xml",
|
|
@@ -1517,30 +1557,34 @@ function be(e, t) {
|
|
|
1517
1557
|
},
|
|
1518
1558
|
{
|
|
1519
1559
|
name: "xl/styles.xml",
|
|
1520
|
-
data: F.encode(
|
|
1560
|
+
data: F.encode(xe)
|
|
1521
1561
|
}
|
|
1522
|
-
]
|
|
1562
|
+
];
|
|
1523
1563
|
}
|
|
1524
1564
|
//#endregion
|
|
1525
1565
|
//#region src/export/export.ts
|
|
1526
|
-
function
|
|
1566
|
+
function V(e, t, n) {
|
|
1527
1567
|
switch (n) {
|
|
1528
|
-
case "csv": return
|
|
1529
|
-
case "tsv": return
|
|
1530
|
-
case "json": return
|
|
1531
|
-
case "xlsx": return
|
|
1568
|
+
case "csv": return H(e, t, ",");
|
|
1569
|
+
case "tsv": return H(e, t, " ");
|
|
1570
|
+
case "json": return De(e, t);
|
|
1571
|
+
case "xlsx": return Ce(e, t);
|
|
1532
1572
|
}
|
|
1533
1573
|
}
|
|
1534
|
-
function
|
|
1574
|
+
async function Te(e, t, n) {
|
|
1575
|
+
let r = n === "xlsx" ? await we(e, t) : V(e, t, n);
|
|
1576
|
+
return new Blob([r], { type: je(n) });
|
|
1577
|
+
}
|
|
1578
|
+
function Ee(e, t) {
|
|
1535
1579
|
return e == null ? "" : (t.type === "date" || t.type === "datetime") && e instanceof Date ? e.toISOString() : String(e);
|
|
1536
1580
|
}
|
|
1537
|
-
function
|
|
1538
|
-
return [t.map((e) =>
|
|
1581
|
+
function H(e, t, n) {
|
|
1582
|
+
return [t.map((e) => U(e.label, n)).join(n), ...e.map((e) => t.map((t) => U(Ee(e[t.key], t), n)).join(n))].join("\n");
|
|
1539
1583
|
}
|
|
1540
|
-
function
|
|
1584
|
+
function U(e, t) {
|
|
1541
1585
|
return e.includes(t) || e.includes("\"") || e.includes("\n") || e.includes("\r") ? "\"" + e.replace(/"/g, "\"\"") + "\"" : e;
|
|
1542
1586
|
}
|
|
1543
|
-
function
|
|
1587
|
+
function De(e, t) {
|
|
1544
1588
|
let n = e.map((e) => {
|
|
1545
1589
|
let n = {};
|
|
1546
1590
|
for (let r of t) {
|
|
@@ -1551,35 +1595,35 @@ function Se(e, t) {
|
|
|
1551
1595
|
});
|
|
1552
1596
|
return JSON.stringify(n, null, 2);
|
|
1553
1597
|
}
|
|
1554
|
-
function
|
|
1555
|
-
let
|
|
1556
|
-
|
|
1598
|
+
function Oe(e, t) {
|
|
1599
|
+
let n = URL.createObjectURL(e), r = document.createElement("a");
|
|
1600
|
+
r.href = n, r.download = t, r.style.display = "none", document.body.appendChild(r), r.click(), document.body.removeChild(r), setTimeout(() => URL.revokeObjectURL(n), 100);
|
|
1557
1601
|
}
|
|
1558
|
-
var
|
|
1602
|
+
var ke = {
|
|
1559
1603
|
csv: "text/csv;charset=utf-8",
|
|
1560
1604
|
tsv: "text/tab-separated-values;charset=utf-8",
|
|
1561
1605
|
json: "application/json;charset=utf-8",
|
|
1562
1606
|
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
1563
|
-
},
|
|
1607
|
+
}, Ae = {
|
|
1564
1608
|
csv: ".csv",
|
|
1565
1609
|
tsv: ".tsv",
|
|
1566
1610
|
json: ".json",
|
|
1567
1611
|
xlsx: ".xlsx"
|
|
1568
1612
|
};
|
|
1569
|
-
function
|
|
1570
|
-
return
|
|
1613
|
+
function je(e) {
|
|
1614
|
+
return ke[e];
|
|
1571
1615
|
}
|
|
1572
|
-
function
|
|
1573
|
-
return
|
|
1616
|
+
function Me(e) {
|
|
1617
|
+
return Ae[e];
|
|
1574
1618
|
}
|
|
1575
1619
|
//#endregion
|
|
1576
1620
|
//#region src/export/xlsx-reader.ts
|
|
1577
|
-
function
|
|
1621
|
+
function Ne(e) {
|
|
1578
1622
|
for (let t = e.byteLength - 22; t >= 0; t--) if (e.getUint32(t, !0) === 101010256) return t;
|
|
1579
1623
|
throw Error("XLSX: End of central directory not found — not a valid ZIP file");
|
|
1580
1624
|
}
|
|
1581
|
-
function
|
|
1582
|
-
let t =
|
|
1625
|
+
function Pe(e) {
|
|
1626
|
+
let t = Ne(e), n = e.getUint32(t + 16, !0), r = e.getUint32(t + 12, !0), i = new TextDecoder("utf-8"), a = [], o = n, s = n + r;
|
|
1583
1627
|
for (; o < s && e.getUint32(o, !0) === 33639248;) {
|
|
1584
1628
|
let t = e.getUint16(o + 10, !0), n = e.getUint32(o + 20, !0), r = e.getUint32(o + 24, !0), s = e.getUint16(o + 28, !0), c = e.getUint16(o + 30, !0), l = e.getUint16(o + 32, !0), u = e.getUint32(o + 42, !0), d = i.decode(new Uint8Array(e.buffer, o + 46, s));
|
|
1585
1629
|
a.push({
|
|
@@ -1592,7 +1636,7 @@ function Oe(e) {
|
|
|
1592
1636
|
}
|
|
1593
1637
|
return a;
|
|
1594
1638
|
}
|
|
1595
|
-
async function
|
|
1639
|
+
async function Fe(e) {
|
|
1596
1640
|
let t = new DecompressionStream("deflate-raw"), n = t.writable.getWriter(), r = t.readable.getReader();
|
|
1597
1641
|
n.write(e), n.close();
|
|
1598
1642
|
let i = [];
|
|
@@ -1605,28 +1649,28 @@ async function ke(e) {
|
|
|
1605
1649
|
for (let e of i) o.set(e, s), s += e.length;
|
|
1606
1650
|
return o;
|
|
1607
1651
|
}
|
|
1608
|
-
async function
|
|
1652
|
+
async function Ie(e, t) {
|
|
1609
1653
|
let n = t.localHeaderOffset, r = e.getUint16(n + 26, !0), i = e.getUint16(n + 28, !0), a = n + 30 + r + i, o = new Uint8Array(e.buffer, a, t.compressedSize);
|
|
1610
1654
|
if (t.compressionMethod === 0) return o.slice();
|
|
1611
|
-
if (t.compressionMethod === 8) return
|
|
1655
|
+
if (t.compressionMethod === 8) return Fe(o);
|
|
1612
1656
|
throw Error(`XLSX: Unsupported compression method ${t.compressionMethod}`);
|
|
1613
1657
|
}
|
|
1614
|
-
async function
|
|
1615
|
-
let t = new DataView(e), n =
|
|
1616
|
-
for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await
|
|
1658
|
+
async function Le(e) {
|
|
1659
|
+
let t = new DataView(e), n = Pe(t), r = /* @__PURE__ */ new Map();
|
|
1660
|
+
for (let e of n) e.compressedSize === 0 && e.name.endsWith("/") || r.set(e.name, await Ie(t, e));
|
|
1617
1661
|
return r;
|
|
1618
1662
|
}
|
|
1619
|
-
var
|
|
1663
|
+
var Re = new TextDecoder("utf-8");
|
|
1620
1664
|
function W(e) {
|
|
1621
|
-
let t =
|
|
1665
|
+
let t = Re.decode(e);
|
|
1622
1666
|
return new DOMParser().parseFromString(t, "application/xml");
|
|
1623
1667
|
}
|
|
1624
|
-
function
|
|
1668
|
+
function ze(e) {
|
|
1625
1669
|
if (!e) return [];
|
|
1626
1670
|
let t = W(e);
|
|
1627
1671
|
return Array.from(t.querySelectorAll("si")).map((e) => Array.from(e.querySelectorAll("t")).map((e) => e.textContent ?? "").join(""));
|
|
1628
1672
|
}
|
|
1629
|
-
var
|
|
1673
|
+
var Be = /* @__PURE__ */ new Set([
|
|
1630
1674
|
14,
|
|
1631
1675
|
15,
|
|
1632
1676
|
16,
|
|
@@ -1646,29 +1690,29 @@ var Pe = /* @__PURE__ */ new Set([
|
|
|
1646
1690
|
57,
|
|
1647
1691
|
58
|
|
1648
1692
|
]);
|
|
1649
|
-
function
|
|
1693
|
+
function Ve(e) {
|
|
1650
1694
|
let t = e.replace(/"[^"]*"/g, "").replace(/\\./g, "").replace(/\[[^\]]*\]/g, "").split(";")[0];
|
|
1651
1695
|
return /[dy]/i.test(t);
|
|
1652
1696
|
}
|
|
1653
|
-
function
|
|
1697
|
+
function He(e) {
|
|
1654
1698
|
let t = /* @__PURE__ */ new Set();
|
|
1655
1699
|
if (!e) return t;
|
|
1656
1700
|
let n = W(e), r = /* @__PURE__ */ new Map();
|
|
1657
1701
|
for (let e of Array.from(n.querySelectorAll("numFmts > numFmt"))) r.set(parseInt(e.getAttribute("numFmtId") ?? "", 10), e.getAttribute("formatCode") ?? "");
|
|
1658
1702
|
return Array.from(n.querySelectorAll("cellXfs > xf")).forEach((e, n) => {
|
|
1659
1703
|
let i = parseInt(e.getAttribute("numFmtId") ?? "0", 10), a = r.get(i);
|
|
1660
|
-
(a === void 0 ?
|
|
1704
|
+
(a === void 0 ? Be.has(i) : Ve(a)) && t.add(n);
|
|
1661
1705
|
}), t;
|
|
1662
1706
|
}
|
|
1663
|
-
function
|
|
1707
|
+
function Ue(e) {
|
|
1664
1708
|
if (!e) return !1;
|
|
1665
1709
|
let t = W(e).querySelector("workbookPr")?.getAttribute("date1904");
|
|
1666
1710
|
return t === "1" || t === "true";
|
|
1667
1711
|
}
|
|
1668
|
-
function
|
|
1712
|
+
function We(e, t) {
|
|
1669
1713
|
return new Date((t ? Date.UTC(1904, 0, 1) : Date.UTC(1899, 11, 30)) + Math.floor(e) * 864e5).toISOString().slice(0, 10);
|
|
1670
1714
|
}
|
|
1671
|
-
function
|
|
1715
|
+
function Ge(e, t, n, r) {
|
|
1672
1716
|
let i = W(e).querySelectorAll("row");
|
|
1673
1717
|
if (i.length === 0) return [];
|
|
1674
1718
|
let a = 0, o = /* @__PURE__ */ new Map();
|
|
@@ -1676,7 +1720,7 @@ function ze(e, t, n, r) {
|
|
|
1676
1720
|
let i = parseInt(e.getAttribute("r") ?? "1", 10) - 1, s = /* @__PURE__ */ new Map();
|
|
1677
1721
|
o.set(i, s);
|
|
1678
1722
|
for (let i of e.querySelectorAll("c")) {
|
|
1679
|
-
let e =
|
|
1723
|
+
let e = Ke(i.getAttribute("r") ?? "");
|
|
1680
1724
|
e > a && (a = e);
|
|
1681
1725
|
let o = i.getAttribute("t") ?? "", c = i.getAttribute("s") ?? "", l = i.querySelector("v")?.textContent ?? "", u = i.querySelector("is > t")?.textContent ?? null, d;
|
|
1682
1726
|
if (o === "s") d = t[parseInt(l, 10)] ?? "";
|
|
@@ -1685,7 +1729,7 @@ function ze(e, t, n, r) {
|
|
|
1685
1729
|
else if (l === "") d = "";
|
|
1686
1730
|
else {
|
|
1687
1731
|
let e = parseFloat(l);
|
|
1688
|
-
d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ?
|
|
1732
|
+
d = c !== "" && n.has(parseInt(c, 10)) && !isNaN(e) && e >= 0 ? We(e, r) : l;
|
|
1689
1733
|
}
|
|
1690
1734
|
s.set(e, d);
|
|
1691
1735
|
}
|
|
@@ -1699,13 +1743,13 @@ function ze(e, t, n, r) {
|
|
|
1699
1743
|
}
|
|
1700
1744
|
return c;
|
|
1701
1745
|
}
|
|
1702
|
-
function
|
|
1746
|
+
function Ke(e) {
|
|
1703
1747
|
let t = 0, n = 0;
|
|
1704
1748
|
for (; n < e.length && e[n] >= "A" && e[n] <= "Z";) t = t * 26 + (e.charCodeAt(n) - 64), n++;
|
|
1705
1749
|
return t - 1;
|
|
1706
1750
|
}
|
|
1707
|
-
async function
|
|
1708
|
-
let t = await
|
|
1751
|
+
async function qe(e) {
|
|
1752
|
+
let t = await Le(e), n = ze(t.get("xl/sharedStrings.xml")), r = t.get("xl/worksheets/sheet1.xml");
|
|
1709
1753
|
if (!r) {
|
|
1710
1754
|
for (let [e, n] of t) if (e.toLowerCase().includes("worksheets/sheet")) {
|
|
1711
1755
|
r = n;
|
|
@@ -1713,7 +1757,7 @@ async function Ve(e) {
|
|
|
1713
1757
|
}
|
|
1714
1758
|
}
|
|
1715
1759
|
if (!r) throw Error("XLSX: No worksheet found");
|
|
1716
|
-
let i =
|
|
1760
|
+
let i = He(t.get("xl/styles.xml")), a = Ue(t.get("xl/workbook.xml")), o = Ge(r, n, i, a);
|
|
1717
1761
|
return o.length === 0 ? {
|
|
1718
1762
|
headers: [],
|
|
1719
1763
|
rows: []
|
|
@@ -1744,7 +1788,7 @@ var q = {
|
|
|
1744
1788
|
lt: "<",
|
|
1745
1789
|
gte: "≥",
|
|
1746
1790
|
lte: "≤"
|
|
1747
|
-
}, J = 120, Y = 40, X = 20, Z = 32, Q = 5,
|
|
1791
|
+
}, J = 120, Y = 40, X = 20, Z = 32, Q = 5, Je = 200, $ = class extends n {
|
|
1748
1792
|
constructor(...e) {
|
|
1749
1793
|
super(...e), this.columns = [], this._data = [], this._inUndoRedo = !1, this.clearUndoOnDataChange = !1, this.clearSelectionOnDataChange = !1, this._rowHeightFromCss = Z, this.showRowNumbers = !1, this.theme = void 0, this.maxRows = 0, this.editable = !0, this.showFilters = !1, this.showContextMenu = !1, this.frozenRows = 0, this.emptyMessage = "No data", this.noMatchingMessage = "No matching data", this.loading = !1, this.importEnabled = !1, this.selectable = !1, this.dataMode = "client", this.footerData = null, this.stylesheets = [], this._scrollTop = 0, this._scrollLeft = 0, this._viewportHeight = 0, this._viewportWidth = 0, this._colLeftOffsets = [], this._totalRowWidth = 0, this._baseStyleSheets = [], this._activeCell = null, this._editingCell = null, this._sortCriteria = [], this._selection = new re(), this._editing = new ie(), this._rowSelection = new j(), this._undo = new M(), this._filters = [], this._filteredIndices = [], this._sortedIndices = [], this._openFilterKey = null, this._rowSelectionVersion = 0, this._lastCheckboxRowIndex = null, this._checkboxShiftPending = !1, this._autocompleteState = null, this._headerMenu = null, this._bodyContextMenu = null, this._commentPopup = null, this._viewDirty = !0, this._isDragging = !1, this._wasDrag = !1, this._resizing = null, this._resizeCleanup = null, this._wasHeaderDrag = !1, this._wasRowDrag = !1, this._colDrag = null, this._colDragIndicatorLeft = null, this._fillDrag = null, this._rowDrag = null, this._rowDragIndicatorY = null, this._findState = null, this._columnWidths = /* @__PURE__ */ new Map(), this._hostResizeObserver = null, this._comments = /* @__PURE__ */ new Map(), this._isDragOver = !1, this._warnedUnconstrained = !1, this._onCommentPopupOutsideClick = () => {
|
|
1750
1794
|
this._commitCommentPopup();
|
|
@@ -2106,17 +2150,34 @@ var q = {
|
|
|
2106
2150
|
return e;
|
|
2107
2151
|
}
|
|
2108
2152
|
exportToString(e, t) {
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
if (!t) return "";
|
|
2112
|
-
let n = this.visibleColumns.slice(t.startCol, t.endCol + 1), r = [];
|
|
2113
|
-
for (let e = t.startRow; e <= t.endRow; e++) r.push(this.data[this._toDataIndex(e)]);
|
|
2114
|
-
return B(r, n, e);
|
|
2115
|
-
}
|
|
2116
|
-
return B(this._sortedIndices.map((e) => this.data[e]), this.visibleColumns, e);
|
|
2153
|
+
let n = this._exportSlice(t);
|
|
2154
|
+
return n ? V(n.rows, n.cols, e) : "";
|
|
2117
2155
|
}
|
|
2118
|
-
|
|
2119
|
-
|
|
2156
|
+
async exportToBlob(e, t) {
|
|
2157
|
+
let n = this._exportSlice(t) ?? {
|
|
2158
|
+
rows: [],
|
|
2159
|
+
cols: []
|
|
2160
|
+
};
|
|
2161
|
+
return Te(n.rows, n.cols, e);
|
|
2162
|
+
}
|
|
2163
|
+
async exportToFile(e, t) {
|
|
2164
|
+
Oe(await this.exportToBlob(e), t ?? `export${Me(e)}`);
|
|
2165
|
+
}
|
|
2166
|
+
_exportSlice(e) {
|
|
2167
|
+
if (e?.selectionOnly) {
|
|
2168
|
+
let e = this._selection.getEffectiveRange();
|
|
2169
|
+
if (!e) return null;
|
|
2170
|
+
let t = this.visibleColumns.slice(e.startCol, e.endCol + 1), n = [];
|
|
2171
|
+
for (let t = e.startRow; t <= e.endRow; t++) n.push(this.data[this._toDataIndex(t)]);
|
|
2172
|
+
return {
|
|
2173
|
+
rows: n,
|
|
2174
|
+
cols: t
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
return {
|
|
2178
|
+
rows: this._sortedIndices.map((e) => this.data[e]),
|
|
2179
|
+
cols: this.visibleColumns
|
|
2180
|
+
};
|
|
2120
2181
|
}
|
|
2121
2182
|
setComment(e, t, n) {
|
|
2122
2183
|
let r = this.getComment(e, t);
|
|
@@ -2173,7 +2234,7 @@ var q = {
|
|
|
2173
2234
|
async importFromFile(e) {
|
|
2174
2235
|
let t = e.name.toLowerCase();
|
|
2175
2236
|
if (t.endsWith(".xlsx")) {
|
|
2176
|
-
let t = await
|
|
2237
|
+
let t = await qe(await e.arrayBuffer());
|
|
2177
2238
|
this._applyImportedSheet(t);
|
|
2178
2239
|
} else if (t.endsWith(".csv") || t.endsWith(".tsv")) {
|
|
2179
2240
|
let t = await e.text(), n = g(t);
|
|
@@ -2396,7 +2457,7 @@ var q = {
|
|
|
2396
2457
|
e !== this._viewportHeight && (this._viewportHeight = e), t !== this._viewportWidth && (this._viewportWidth = t), this._warnIfUnconstrained();
|
|
2397
2458
|
}
|
|
2398
2459
|
_warnIfUnconstrained() {
|
|
2399
|
-
this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount <
|
|
2460
|
+
this._warnedUnconstrained || process.env.NODE_ENV === "production" || this._visibleRowCount < Je || this.scrollHeight > this.clientHeight + 1 || (this._warnedUnconstrained = !0, console.warn(`[@iyulab/flex-table] ${this._visibleRowCount} rows but the host has no height constraint — it grew to fit every row, so virtual scrolling is off and all rows are rendered. Give the host a height (e.g. height: 400px, or flex: 1 1 auto with min-height: 0 inside a sized parent) so it becomes the scroll container.`));
|
|
2400
2461
|
}
|
|
2401
2462
|
_onScroll() {
|
|
2402
2463
|
this._scrollTop = this.scrollTop, this._scrollLeft = this.scrollLeft;
|
|
@@ -4394,4 +4455,4 @@ K([s({ type: Array })], $.prototype, "columns", void 0), K([s({
|
|
|
4394
4455
|
attribute: "max-undo-size"
|
|
4395
4456
|
})], $.prototype, "maxUndoSize", null), K([c()], $.prototype, "_scrollTop", void 0), K([c()], $.prototype, "_scrollLeft", void 0), K([c()], $.prototype, "_viewportHeight", void 0), K([c()], $.prototype, "_viewportWidth", void 0), K([c()], $.prototype, "_activeCell", void 0), K([c()], $.prototype, "_editingCell", void 0), K([c()], $.prototype, "_sortCriteria", void 0), K([c()], $.prototype, "_openFilterKey", void 0), K([c()], $.prototype, "_rowSelectionVersion", void 0), K([c()], $.prototype, "_autocompleteState", void 0), K([c()], $.prototype, "_headerMenu", void 0), K([c()], $.prototype, "_bodyContextMenu", void 0), K([c()], $.prototype, "_commentPopup", void 0), K([c()], $.prototype, "_isDragOver", void 0), $ = K([o("flex-table")], $);
|
|
4396
4457
|
//#endregion
|
|
4397
|
-
export { j as a, M as i, G as n, k as o,
|
|
4458
|
+
export { j as a, M as i, G as n, k as o, V as r, w as s, $ as t };
|
package/dist/flex-table.d.ts
CHANGED
|
@@ -251,16 +251,27 @@ export declare class FlexTable extends LitElement {
|
|
|
251
251
|
}>): void;
|
|
252
252
|
private _createEmptyRow;
|
|
253
253
|
/**
|
|
254
|
-
* Export table data to string in the specified format.
|
|
254
|
+
* Export table data to string in the specified format. Synchronous — XLSX comes back as an
|
|
255
|
+
* uncompressed workbook; use `exportToBlob` for a compressed one.
|
|
255
256
|
* @param options.selectionOnly - Export only the currently selected range
|
|
256
257
|
*/
|
|
257
258
|
exportToString(format: ExportFormat, options?: {
|
|
258
259
|
selectionOnly?: boolean;
|
|
259
260
|
}): string | Uint8Array<ArrayBuffer>;
|
|
260
261
|
/**
|
|
261
|
-
* Export table data
|
|
262
|
+
* Export table data as a `Blob` of the format's MIME type. XLSX is DEFLATE-compressed.
|
|
263
|
+
* @param options.selectionOnly - Export only the currently selected range
|
|
264
|
+
*/
|
|
265
|
+
exportToBlob(format: ExportFormat, options?: {
|
|
266
|
+
selectionOnly?: boolean;
|
|
267
|
+
}): Promise<Blob>;
|
|
268
|
+
/**
|
|
269
|
+
* Export table data and trigger file download. XLSX is DEFLATE-compressed; the promise settles
|
|
270
|
+
* once the download has been handed to the browser.
|
|
262
271
|
*/
|
|
263
|
-
exportToFile(format: ExportFormat, filename?: string): void
|
|
272
|
+
exportToFile(format: ExportFormat, filename?: string): Promise<void>;
|
|
273
|
+
/** 내보낼 행·열 — 선택만이면 선택 범위(없으면 `null`), 아니면 정렬 순서의 전체 행 · 보이는 열. */
|
|
274
|
+
private _exportSlice;
|
|
264
275
|
/**
|
|
265
276
|
* Set a comment on the cell at the given data index and column key.
|
|
266
277
|
* Pass an empty string or null to remove the comment.
|
package/dist/flex-table.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./flex-table-
|
|
1
|
+
import { a as e, i as t, n, o as r, r as i, s as a, t as o } from "./flex-table-MnSI0Ogl.js";
|
|
2
2
|
export { o as FlexTable, e as RowSelectionState, t as UndoStack, n as effectiveAlign, i as exportData, r as flexTableLocale, a as renderCell };
|
package/dist/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "./flex-table-
|
|
1
|
+
import { t as e } from "./flex-table-MnSI0Ogl.js";
|
|
2
2
|
import { i as t, t as n } from "./query-Dw4iO0ir.js";
|
|
3
3
|
import { t as r } from "./view-DiLr-TdY.js";
|
|
4
4
|
import i, { useCallback as a, useEffect as o, useMemo as s, useRef as c, useState as l } from "react";
|
package/package.json
CHANGED
|
@@ -127,8 +127,9 @@ Enter/Escape and blur-to-commit behavior.
|
|
|
127
127
|
| `setComment(dataIndex, colKey, text)` | `null` or `''` removes; undoable |
|
|
128
128
|
| `getComment(dataIndex, colKey)` / `clearComments()` | |
|
|
129
129
|
| `importFromFile(file)` | `Promise<void>`; `.xlsx`, `.csv`, `.tsv`; fires `data-import` |
|
|
130
|
-
| `exportToString(format, { selectionOnly? })` | `string \| Uint8Array`; format `'csv' \| 'tsv' \| 'json' \| 'xlsx'` (xlsx returns bytes) |
|
|
131
|
-
| `
|
|
130
|
+
| `exportToString(format, { selectionOnly? })` | `string \| Uint8Array`; format `'csv' \| 'tsv' \| 'json' \| 'xlsx'` (xlsx returns uncompressed bytes — synchronous) |
|
|
131
|
+
| `exportToBlob(format, { selectionOnly? })` | `Promise<Blob>` typed with the format's MIME; xlsx is DEFLATE-compressed |
|
|
132
|
+
| `exportToFile(format, filename?)` | `Promise<void>` — triggers a download (xlsx compressed) |
|
|
132
133
|
|
|
133
134
|
## Events
|
|
134
135
|
|