odf-kit 0.9.8 → 0.9.9
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/xlsx/converter.d.ts +31 -0
- package/dist/xlsx/converter.d.ts.map +1 -0
- package/dist/xlsx/converter.js +132 -0
- package/dist/xlsx/converter.js.map +1 -0
- package/dist/xlsx/index.d.ts +23 -0
- package/dist/xlsx/index.d.ts.map +1 -0
- package/dist/xlsx/index.js +25 -0
- package/dist/xlsx/index.js.map +1 -0
- package/dist/xlsx/reader.d.ts +82 -0
- package/dist/xlsx/reader.d.ts.map +1 -0
- package/dist/xlsx/reader.js +449 -0
- package/dist/xlsx/reader.js.map +1 -0
- package/package.json +5 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XLSX → ODS converter.
|
|
3
|
+
*
|
|
4
|
+
* Maps an XlsxWorkbook intermediate model to an OdsDocument and saves it.
|
|
5
|
+
*/
|
|
6
|
+
import type { OdsDateFormat } from "../ods/types.js";
|
|
7
|
+
import type { XlsxWorkbook } from "./reader.js";
|
|
8
|
+
export interface XlsxToOdsOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Date display format for date cells.
|
|
11
|
+
* Defaults to "YYYY-MM-DD".
|
|
12
|
+
*/
|
|
13
|
+
dateFormat?: OdsDateFormat;
|
|
14
|
+
/**
|
|
15
|
+
* Document metadata for the output ODS file.
|
|
16
|
+
*/
|
|
17
|
+
metadata?: {
|
|
18
|
+
title?: string;
|
|
19
|
+
creator?: string;
|
|
20
|
+
description?: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Convert an XlsxWorkbook model to an ODS file.
|
|
25
|
+
*
|
|
26
|
+
* @param workbook - Parsed XLSX workbook from readXlsx().
|
|
27
|
+
* @param options - Conversion options.
|
|
28
|
+
* @returns Promise resolving to a Uint8Array containing the .ods file.
|
|
29
|
+
*/
|
|
30
|
+
export declare function convertXlsxToOds(workbook: XlsxWorkbook, options?: XlsxToOdsOptions): Promise<Uint8Array>;
|
|
31
|
+
//# sourceMappingURL=converter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter.d.ts","sourceRoot":"","sources":["../../src/xlsx/converter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,EAAE;QACT,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAuHD;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,YAAY,EACtB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAYrB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XLSX → ODS converter.
|
|
3
|
+
*
|
|
4
|
+
* Maps an XlsxWorkbook intermediate model to an OdsDocument and saves it.
|
|
5
|
+
*/
|
|
6
|
+
import { OdsDocument } from "../ods/document.js";
|
|
7
|
+
// ─── Cell Mapping ─────────────────────────────────────────────────────
|
|
8
|
+
function mapCell(cell, options) {
|
|
9
|
+
switch (cell.type) {
|
|
10
|
+
case "string":
|
|
11
|
+
return { value: cell.value, type: "string" };
|
|
12
|
+
case "number":
|
|
13
|
+
return { value: cell.value, type: "float" };
|
|
14
|
+
case "boolean":
|
|
15
|
+
return { value: cell.value, type: "boolean" };
|
|
16
|
+
case "date":
|
|
17
|
+
return {
|
|
18
|
+
value: cell.value,
|
|
19
|
+
type: "date",
|
|
20
|
+
...(options.dateFormat ? { dateFormat: options.dateFormat } : {}),
|
|
21
|
+
};
|
|
22
|
+
case "formula": {
|
|
23
|
+
// Determine the cell type from the cached value
|
|
24
|
+
const val = cell.value;
|
|
25
|
+
let type = "formula";
|
|
26
|
+
if (typeof val === "string")
|
|
27
|
+
type = "formula";
|
|
28
|
+
else if (typeof val === "boolean")
|
|
29
|
+
type = "formula";
|
|
30
|
+
else if (val instanceof Date)
|
|
31
|
+
type = "formula";
|
|
32
|
+
else
|
|
33
|
+
type = "formula";
|
|
34
|
+
return {
|
|
35
|
+
value: val,
|
|
36
|
+
type,
|
|
37
|
+
formula: cell.formula ? `=${cell.formula.replace(/^=/, "")}` : undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
case "error":
|
|
41
|
+
// Represent errors as strings
|
|
42
|
+
return { value: String(cell.value), type: "string" };
|
|
43
|
+
default:
|
|
44
|
+
return { value: null, type: "string" };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// ─── Sheet Conversion ─────────────────────────────────────────────────
|
|
48
|
+
function convertSheet(xlSheet, options, doc) {
|
|
49
|
+
const sheet = doc.addSheet(xlSheet.name);
|
|
50
|
+
if (xlSheet.freezeRows)
|
|
51
|
+
sheet.freezeRows(xlSheet.freezeRows);
|
|
52
|
+
if (xlSheet.freezeColumns)
|
|
53
|
+
sheet.freezeColumns(xlSheet.freezeColumns);
|
|
54
|
+
if (xlSheet.rows.size === 0)
|
|
55
|
+
return;
|
|
56
|
+
// Determine row/column extent
|
|
57
|
+
let maxRow = 0;
|
|
58
|
+
let maxCol = 0;
|
|
59
|
+
for (const [rowIdx, row] of xlSheet.rows) {
|
|
60
|
+
if (rowIdx > maxRow)
|
|
61
|
+
maxRow = rowIdx;
|
|
62
|
+
for (const colIdx of row.cells.keys()) {
|
|
63
|
+
if (colIdx > maxCol)
|
|
64
|
+
maxCol = colIdx;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Also account for merge extents
|
|
68
|
+
for (const [key, span] of xlSheet.merges) {
|
|
69
|
+
const [c, r] = key.split(":").map(Number);
|
|
70
|
+
const endRow = r + span.rowSpan - 1;
|
|
71
|
+
const endCol = c + span.colSpan - 1;
|
|
72
|
+
if (endRow > maxRow)
|
|
73
|
+
maxRow = endRow;
|
|
74
|
+
if (endCol > maxCol)
|
|
75
|
+
maxCol = endCol;
|
|
76
|
+
}
|
|
77
|
+
for (let r = 0; r <= maxRow; r++) {
|
|
78
|
+
const xlRow = xlSheet.rows.get(r);
|
|
79
|
+
const cells = [];
|
|
80
|
+
let hasContent = false;
|
|
81
|
+
for (let c = 0; c <= maxCol; c++) {
|
|
82
|
+
const cellKey = `${c}:${r}`;
|
|
83
|
+
// Skip covered cells — OdsDocument handles them automatically via colSpan/rowSpan
|
|
84
|
+
if (xlSheet.coveredCells.has(cellKey)) {
|
|
85
|
+
cells.push(null);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
const xlCell = xlRow?.cells.get(c);
|
|
89
|
+
if (!xlCell || xlCell.type === "empty") {
|
|
90
|
+
cells.push(null);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const cellObj = mapCell(xlCell, options);
|
|
94
|
+
// Apply merge spans
|
|
95
|
+
const merge = xlSheet.merges.get(cellKey);
|
|
96
|
+
if (merge) {
|
|
97
|
+
if (merge.colSpan > 1)
|
|
98
|
+
cellObj.colSpan = merge.colSpan;
|
|
99
|
+
if (merge.rowSpan > 1)
|
|
100
|
+
cellObj.rowSpan = merge.rowSpan;
|
|
101
|
+
}
|
|
102
|
+
cells.push(cellObj);
|
|
103
|
+
hasContent = true;
|
|
104
|
+
}
|
|
105
|
+
if (hasContent) {
|
|
106
|
+
sheet.addRow(cells);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// Emit an empty row to preserve row positioning
|
|
110
|
+
sheet.addRow([]);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// ─── Public API ───────────────────────────────────────────────────────
|
|
115
|
+
/**
|
|
116
|
+
* Convert an XlsxWorkbook model to an ODS file.
|
|
117
|
+
*
|
|
118
|
+
* @param workbook - Parsed XLSX workbook from readXlsx().
|
|
119
|
+
* @param options - Conversion options.
|
|
120
|
+
* @returns Promise resolving to a Uint8Array containing the .ods file.
|
|
121
|
+
*/
|
|
122
|
+
export async function convertXlsxToOds(workbook, options = {}) {
|
|
123
|
+
const doc = new OdsDocument();
|
|
124
|
+
if (options.metadata) {
|
|
125
|
+
doc.setMetadata(options.metadata);
|
|
126
|
+
}
|
|
127
|
+
for (const xlSheet of workbook.sheets) {
|
|
128
|
+
convertSheet(xlSheet, options, doc);
|
|
129
|
+
}
|
|
130
|
+
return doc.save();
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=converter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"converter.js","sourceRoot":"","sources":["../../src/xlsx/converter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { XlsxToOdsOptions } from "./converter.js";
|
|
2
|
+
export { readXlsx } from "./reader.js";
|
|
3
|
+
export type { XlsxWorkbook, XlsxSheet, XlsxRow, XlsxCell } from "./reader.js";
|
|
4
|
+
export type { XlsxToOdsOptions } from "./converter.js";
|
|
5
|
+
/**
|
|
6
|
+
* Convert an .xlsx file to an .ods file.
|
|
7
|
+
*
|
|
8
|
+
* Parses the XLSX XML directly — no external dependencies beyond fflate.
|
|
9
|
+
* Runs in Node.js and browsers.
|
|
10
|
+
*
|
|
11
|
+
* @param bytes - Raw .xlsx file bytes (Uint8Array or ArrayBuffer).
|
|
12
|
+
* @param options - Optional conversion options.
|
|
13
|
+
* @returns Promise resolving to a Uint8Array containing the .ods file.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* import { xlsxToOds } from "odf-kit/xlsx"
|
|
17
|
+
* import { readFileSync, writeFileSync } from "fs"
|
|
18
|
+
*
|
|
19
|
+
* const bytes = await xlsxToOds(readFileSync("report.xlsx"))
|
|
20
|
+
* writeFileSync("report.ods", bytes)
|
|
21
|
+
*/
|
|
22
|
+
export declare function xlsxToOds(bytes: Uint8Array | ArrayBuffer, options?: XlsxToOdsOptions): Promise<Uint8Array>;
|
|
23
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/xlsx/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC9E,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,UAAU,GAAG,WAAW,EAC/B,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,UAAU,CAAC,CAGrB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { readXlsx } from "./reader.js";
|
|
2
|
+
import { convertXlsxToOds } from "./converter.js";
|
|
3
|
+
export { readXlsx } from "./reader.js";
|
|
4
|
+
/**
|
|
5
|
+
* Convert an .xlsx file to an .ods file.
|
|
6
|
+
*
|
|
7
|
+
* Parses the XLSX XML directly — no external dependencies beyond fflate.
|
|
8
|
+
* Runs in Node.js and browsers.
|
|
9
|
+
*
|
|
10
|
+
* @param bytes - Raw .xlsx file bytes (Uint8Array or ArrayBuffer).
|
|
11
|
+
* @param options - Optional conversion options.
|
|
12
|
+
* @returns Promise resolving to a Uint8Array containing the .ods file.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* import { xlsxToOds } from "odf-kit/xlsx"
|
|
16
|
+
* import { readFileSync, writeFileSync } from "fs"
|
|
17
|
+
*
|
|
18
|
+
* const bytes = await xlsxToOds(readFileSync("report.xlsx"))
|
|
19
|
+
* writeFileSync("report.ods", bytes)
|
|
20
|
+
*/
|
|
21
|
+
export async function xlsxToOds(bytes, options) {
|
|
22
|
+
const workbook = readXlsx(bytes);
|
|
23
|
+
return convertXlsxToOds(workbook, options);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/xlsx/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGlD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIvC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAA+B,EAC/B,OAA0B;IAE1B,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XLSX reader — parses an .xlsx file into an intermediate XlsxWorkbook model.
|
|
3
|
+
*
|
|
4
|
+
* Parsing pipeline:
|
|
5
|
+
* 1. Unzip the .xlsx bytes with fflate
|
|
6
|
+
* 2. Parse xl/workbook.xml → sheet names and rIds
|
|
7
|
+
* 3. Parse xl/_rels/workbook.xml.rels → rId → file path map
|
|
8
|
+
* 4. Parse xl/sharedStrings.xml → string lookup array
|
|
9
|
+
* 5. Parse xl/styles.xml → style index → date format detection
|
|
10
|
+
* 6. Parse each xl/worksheets/sheet*.xml → rows, cells, merges, freeze
|
|
11
|
+
* 7. Return XlsxWorkbook
|
|
12
|
+
*
|
|
13
|
+
* No external dependencies — uses fflate for ZIP and our existing xml-parser.
|
|
14
|
+
*/
|
|
15
|
+
export interface XlsxWorkbook {
|
|
16
|
+
sheets: XlsxSheet[];
|
|
17
|
+
}
|
|
18
|
+
export interface XlsxSheet {
|
|
19
|
+
name: string;
|
|
20
|
+
/** rowIndex → row */
|
|
21
|
+
rows: Map<number, XlsxRow>;
|
|
22
|
+
/** "col:row" → merge span for primary cell */
|
|
23
|
+
merges: Map<string, {
|
|
24
|
+
colSpan: number;
|
|
25
|
+
rowSpan: number;
|
|
26
|
+
}>;
|
|
27
|
+
/** Set of "col:row" keys that are covered by a merge (non-primary) */
|
|
28
|
+
coveredCells: Set<string>;
|
|
29
|
+
freezeRows?: number;
|
|
30
|
+
freezeColumns?: number;
|
|
31
|
+
}
|
|
32
|
+
export interface XlsxRow {
|
|
33
|
+
/** colIndex → cell */
|
|
34
|
+
cells: Map<number, XlsxCell>;
|
|
35
|
+
}
|
|
36
|
+
export interface XlsxCell {
|
|
37
|
+
type: "string" | "number" | "boolean" | "date" | "formula" | "error" | "empty";
|
|
38
|
+
value: string | number | boolean | Date | null;
|
|
39
|
+
/** Original formula string, if cell has a formula. */
|
|
40
|
+
formula?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse a cell reference like "A1", "Z3", "AA10" into zero-based col/row indices.
|
|
44
|
+
*/
|
|
45
|
+
export declare function parseCellRef(ref: string): {
|
|
46
|
+
col: number;
|
|
47
|
+
row: number;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Parse a merge range like "A1:C2" into start position and span.
|
|
51
|
+
*/
|
|
52
|
+
export declare function parseMergeRef(ref: string): {
|
|
53
|
+
startCol: number;
|
|
54
|
+
startRow: number;
|
|
55
|
+
colSpan: number;
|
|
56
|
+
rowSpan: number;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Returns true if a custom number format code represents a date/time.
|
|
60
|
+
* Strips quoted strings first, then checks for date tokens (y, m, d, h).
|
|
61
|
+
*/
|
|
62
|
+
export declare function isDateFormatCode(code: string): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Returns true if the given style index refers to a date/time format.
|
|
65
|
+
*/
|
|
66
|
+
export declare function isDateStyle(styleIndex: number, cellXfs: number[], customFormats: Map<number, string>): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Convert an XLSX serial date number to a JavaScript Date (UTC).
|
|
69
|
+
*
|
|
70
|
+
* Excel stores dates as days since January 0, 1900, with a deliberate
|
|
71
|
+
* off-by-one bug inherited from Lotus 1-2-3 (Excel incorrectly treats
|
|
72
|
+
* 1900 as a leap year). The correct epoch is December 30, 1899 UTC.
|
|
73
|
+
*/
|
|
74
|
+
export declare function xlsxSerialToDate(serial: number): Date;
|
|
75
|
+
/**
|
|
76
|
+
* Parse an XLSX file into an intermediate XlsxWorkbook model.
|
|
77
|
+
*
|
|
78
|
+
* @param bytes - Raw .xlsx file bytes (Uint8Array or ArrayBuffer).
|
|
79
|
+
* @returns XlsxWorkbook with typed cell values.
|
|
80
|
+
*/
|
|
81
|
+
export declare function readXlsx(bytes: Uint8Array | ArrayBuffer): XlsxWorkbook;
|
|
82
|
+
//# sourceMappingURL=reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/xlsx/reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3B,8CAA8C;IAC9C,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,sEAAsE;IACtE,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,sBAAsB;IACtB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/E,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,CAAC;IAC/C,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkCD;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAUtE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB,CAUA;AA2CD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMtD;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EAAE,EACjB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,OAAO,CAMT;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAUrD;AAsRD;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,YAAY,CA2CtE"}
|
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XLSX reader — parses an .xlsx file into an intermediate XlsxWorkbook model.
|
|
3
|
+
*
|
|
4
|
+
* Parsing pipeline:
|
|
5
|
+
* 1. Unzip the .xlsx bytes with fflate
|
|
6
|
+
* 2. Parse xl/workbook.xml → sheet names and rIds
|
|
7
|
+
* 3. Parse xl/_rels/workbook.xml.rels → rId → file path map
|
|
8
|
+
* 4. Parse xl/sharedStrings.xml → string lookup array
|
|
9
|
+
* 5. Parse xl/styles.xml → style index → date format detection
|
|
10
|
+
* 6. Parse each xl/worksheets/sheet*.xml → rows, cells, merges, freeze
|
|
11
|
+
* 7. Return XlsxWorkbook
|
|
12
|
+
*
|
|
13
|
+
* No external dependencies — uses fflate for ZIP and our existing xml-parser.
|
|
14
|
+
*/
|
|
15
|
+
import { unzipSync, strFromU8 } from "fflate";
|
|
16
|
+
import { parseXml } from "../reader/xml-parser.js";
|
|
17
|
+
// ─── XML Helpers ──────────────────────────────────────────────────────
|
|
18
|
+
/** Strip namespace prefix from tag name: "ss:sheet" → "sheet", "sheet" → "sheet" */
|
|
19
|
+
function localName(tag) {
|
|
20
|
+
const colon = tag.indexOf(":");
|
|
21
|
+
return colon === -1 ? tag : tag.slice(colon + 1);
|
|
22
|
+
}
|
|
23
|
+
/** Find first child whose local name matches, ignoring namespace prefix. */
|
|
24
|
+
function findLocal(node, local) {
|
|
25
|
+
for (const child of node.children) {
|
|
26
|
+
if (child.type === "element" && localName(child.tag) === local)
|
|
27
|
+
return child;
|
|
28
|
+
}
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
function findLocals(node, local) {
|
|
32
|
+
return node.children.filter((c) => c.type === "element" && localName(c.tag) === local);
|
|
33
|
+
}
|
|
34
|
+
/** Get text content of all direct text children. */
|
|
35
|
+
function textContent(node) {
|
|
36
|
+
return node.children
|
|
37
|
+
.filter((c) => c.type === "text")
|
|
38
|
+
.map((c) => c.text)
|
|
39
|
+
.join("");
|
|
40
|
+
}
|
|
41
|
+
// ─── Cell Reference Parsing ───────────────────────────────────────────
|
|
42
|
+
/**
|
|
43
|
+
* Parse a cell reference like "A1", "Z3", "AA10" into zero-based col/row indices.
|
|
44
|
+
*/
|
|
45
|
+
export function parseCellRef(ref) {
|
|
46
|
+
const match = ref.match(/^([A-Z]+)(\d+)$/);
|
|
47
|
+
if (!match)
|
|
48
|
+
throw new Error(`Invalid cell reference: ${ref}`);
|
|
49
|
+
const colStr = match[1];
|
|
50
|
+
const rowStr = match[2];
|
|
51
|
+
let col = 0;
|
|
52
|
+
for (const ch of colStr) {
|
|
53
|
+
col = col * 26 + (ch.charCodeAt(0) - 64);
|
|
54
|
+
}
|
|
55
|
+
return { col: col - 1, row: parseInt(rowStr, 10) - 1 };
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parse a merge range like "A1:C2" into start position and span.
|
|
59
|
+
*/
|
|
60
|
+
export function parseMergeRef(ref) {
|
|
61
|
+
const [start, end] = ref.split(":");
|
|
62
|
+
const s = parseCellRef(start);
|
|
63
|
+
const e = parseCellRef(end);
|
|
64
|
+
return {
|
|
65
|
+
startCol: s.col,
|
|
66
|
+
startRow: s.row,
|
|
67
|
+
colSpan: e.col - s.col + 1,
|
|
68
|
+
rowSpan: e.row - s.row + 1,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// ─── Date Handling ────────────────────────────────────────────────────
|
|
72
|
+
/**
|
|
73
|
+
* Built-in XLSX numFmtId values that represent date or time formats.
|
|
74
|
+
* These are defined by the OOXML spec and always mean date/time regardless
|
|
75
|
+
* of any custom numFmts definitions.
|
|
76
|
+
*/
|
|
77
|
+
const BUILTIN_DATE_FORMAT_IDS = new Set([
|
|
78
|
+
14,
|
|
79
|
+
15,
|
|
80
|
+
16,
|
|
81
|
+
17, // m/d/yy variants
|
|
82
|
+
18,
|
|
83
|
+
19,
|
|
84
|
+
20,
|
|
85
|
+
21,
|
|
86
|
+
22, // h:mm variants and m/d/yy h:mm
|
|
87
|
+
27,
|
|
88
|
+
28,
|
|
89
|
+
29,
|
|
90
|
+
30,
|
|
91
|
+
31, // CJK date formats
|
|
92
|
+
32,
|
|
93
|
+
33,
|
|
94
|
+
34,
|
|
95
|
+
35,
|
|
96
|
+
36, // CJK time/date formats
|
|
97
|
+
45,
|
|
98
|
+
46,
|
|
99
|
+
47, // mm:ss variants
|
|
100
|
+
50,
|
|
101
|
+
51,
|
|
102
|
+
52,
|
|
103
|
+
53,
|
|
104
|
+
54, // more CJK
|
|
105
|
+
55,
|
|
106
|
+
56,
|
|
107
|
+
57,
|
|
108
|
+
58, // more CJK
|
|
109
|
+
]);
|
|
110
|
+
/**
|
|
111
|
+
* Returns true if a custom number format code represents a date/time.
|
|
112
|
+
* Strips quoted strings first, then checks for date tokens (y, m, d, h).
|
|
113
|
+
*/
|
|
114
|
+
export function isDateFormatCode(code) {
|
|
115
|
+
// Remove quoted literals like "yyyy" or "mm"
|
|
116
|
+
const stripped = code.replace(/"[^"]*"/g, "").toLowerCase();
|
|
117
|
+
// Remove numeric format tokens that look like date chars but aren't
|
|
118
|
+
if (/^[#0,. %]+$/.test(stripped))
|
|
119
|
+
return false;
|
|
120
|
+
return /[ymd]/.test(stripped);
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Returns true if the given style index refers to a date/time format.
|
|
124
|
+
*/
|
|
125
|
+
export function isDateStyle(styleIndex, cellXfs, customFormats) {
|
|
126
|
+
if (styleIndex < 0 || styleIndex >= cellXfs.length)
|
|
127
|
+
return false;
|
|
128
|
+
const numFmtId = cellXfs[styleIndex];
|
|
129
|
+
if (BUILTIN_DATE_FORMAT_IDS.has(numFmtId))
|
|
130
|
+
return true;
|
|
131
|
+
const custom = customFormats.get(numFmtId);
|
|
132
|
+
return custom !== undefined && isDateFormatCode(custom);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Convert an XLSX serial date number to a JavaScript Date (UTC).
|
|
136
|
+
*
|
|
137
|
+
* Excel stores dates as days since January 0, 1900, with a deliberate
|
|
138
|
+
* off-by-one bug inherited from Lotus 1-2-3 (Excel incorrectly treats
|
|
139
|
+
* 1900 as a leap year). The correct epoch is December 30, 1899 UTC.
|
|
140
|
+
*/
|
|
141
|
+
export function xlsxSerialToDate(serial) {
|
|
142
|
+
// Excel serial 1 = January 1, 1900. Epoch = December 31, 1899.
|
|
143
|
+
// Excel incorrectly treats 1900 as a leap year (serial 60 = Feb 29, 1900,
|
|
144
|
+
// which never existed). For serials > 60, subtract 1 to correct this.
|
|
145
|
+
// serial 1 → no correction → Dec 31 + 1 day = Jan 1, 1900 ✓
|
|
146
|
+
// serial 25569 → corrected to 25568 → Dec 31 + 25568 days = Jan 1, 1970 ✓
|
|
147
|
+
const corrected = serial > 60 ? serial - 1 : serial;
|
|
148
|
+
const epoch = Date.UTC(1899, 11, 31); // December 31, 1899
|
|
149
|
+
const ms = Math.round(corrected * 24 * 60 * 60 * 1000);
|
|
150
|
+
return new Date(epoch + ms);
|
|
151
|
+
}
|
|
152
|
+
function parseStyles(xml) {
|
|
153
|
+
const cellXfs = [];
|
|
154
|
+
const customFormats = new Map();
|
|
155
|
+
try {
|
|
156
|
+
const root = parseXml(xml);
|
|
157
|
+
// Custom numFmts
|
|
158
|
+
const numFmtsEl = findLocal(root, "numFmts");
|
|
159
|
+
if (numFmtsEl) {
|
|
160
|
+
for (const fmt of findLocals(numFmtsEl, "numFmt")) {
|
|
161
|
+
const id = parseInt(fmt.attrs["numFmtId"] ?? "-1", 10);
|
|
162
|
+
const code = fmt.attrs["formatCode"] ?? "";
|
|
163
|
+
if (id >= 0)
|
|
164
|
+
customFormats.set(id, code);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
// cellXfs
|
|
168
|
+
const cellXfsEl = findLocal(root, "cellXfs");
|
|
169
|
+
if (cellXfsEl) {
|
|
170
|
+
for (const xf of findLocals(cellXfsEl, "xf")) {
|
|
171
|
+
const numFmtId = parseInt(xf.attrs["numFmtId"] ?? "0", 10);
|
|
172
|
+
cellXfs.push(numFmtId);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
// Malformed styles.xml — return empty, cells won't be detected as dates
|
|
178
|
+
}
|
|
179
|
+
return { cellXfs, customFormats };
|
|
180
|
+
}
|
|
181
|
+
// ─── Shared Strings Parser ────────────────────────────────────────────
|
|
182
|
+
function parseSharedStrings(xml) {
|
|
183
|
+
const strings = [];
|
|
184
|
+
try {
|
|
185
|
+
const root = parseXml(xml);
|
|
186
|
+
for (const si of findLocals(root, "si")) {
|
|
187
|
+
// Simple case: <si><t>text</t></si>
|
|
188
|
+
const t = findLocal(si, "t");
|
|
189
|
+
if (t) {
|
|
190
|
+
strings.push(textContent(t));
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
// Rich text case: <si><r><t>part1</t></r><r><t>part2</t></r></si>
|
|
194
|
+
const parts = [];
|
|
195
|
+
for (const r of findLocals(si, "r")) {
|
|
196
|
+
const rt = findLocal(r, "t");
|
|
197
|
+
if (rt)
|
|
198
|
+
parts.push(textContent(rt));
|
|
199
|
+
}
|
|
200
|
+
strings.push(parts.join(""));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
// Malformed sharedStrings.xml — return empty array
|
|
205
|
+
}
|
|
206
|
+
return strings;
|
|
207
|
+
}
|
|
208
|
+
function parseWorkbook(xml) {
|
|
209
|
+
const sheets = [];
|
|
210
|
+
try {
|
|
211
|
+
const root = parseXml(xml);
|
|
212
|
+
const sheetsEl = findLocal(root, "sheets");
|
|
213
|
+
if (sheetsEl) {
|
|
214
|
+
for (const sheet of findLocals(sheetsEl, "sheet")) {
|
|
215
|
+
const name = sheet.attrs["name"] ?? "Sheet";
|
|
216
|
+
// rId may be "r:id" or "relationships:id" depending on namespace
|
|
217
|
+
const rId = sheet.attrs["r:id"] ??
|
|
218
|
+
Object.entries(sheet.attrs).find(([k]) => k.endsWith(":id"))?.[1] ??
|
|
219
|
+
"";
|
|
220
|
+
if (rId)
|
|
221
|
+
sheets.push({ name, rId });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
// Malformed workbook.xml
|
|
227
|
+
}
|
|
228
|
+
return sheets;
|
|
229
|
+
}
|
|
230
|
+
function parseWorkbookRels(xml) {
|
|
231
|
+
const map = new Map();
|
|
232
|
+
try {
|
|
233
|
+
const root = parseXml(xml);
|
|
234
|
+
for (const rel of findLocals(root, "Relationship")) {
|
|
235
|
+
const id = rel.attrs["Id"] ?? "";
|
|
236
|
+
const target = rel.attrs["Target"] ?? "";
|
|
237
|
+
const type = rel.attrs["Type"] ?? "";
|
|
238
|
+
if (id && target && type.includes("worksheet")) {
|
|
239
|
+
// Normalize path: Target may be "worksheets/sheet1.xml" → "xl/worksheets/sheet1.xml"
|
|
240
|
+
const path = target.startsWith("xl/") ? target : `xl/${target}`;
|
|
241
|
+
map.set(id, path);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
catch {
|
|
246
|
+
// Malformed rels
|
|
247
|
+
}
|
|
248
|
+
return map;
|
|
249
|
+
}
|
|
250
|
+
// ─── Sheet Parser ─────────────────────────────────────────────────────
|
|
251
|
+
function parseSheet(xml, sharedStrings, styles) {
|
|
252
|
+
const rows = new Map();
|
|
253
|
+
const merges = new Map();
|
|
254
|
+
const coveredCells = new Set();
|
|
255
|
+
let freezeRows;
|
|
256
|
+
let freezeColumns;
|
|
257
|
+
try {
|
|
258
|
+
const root = parseXml(xml);
|
|
259
|
+
// Freeze pane from sheetView
|
|
260
|
+
const sheetViews = findLocal(root, "sheetViews");
|
|
261
|
+
if (sheetViews) {
|
|
262
|
+
const sheetView = findLocal(sheetViews, "sheetView");
|
|
263
|
+
if (sheetView) {
|
|
264
|
+
const pane = findLocal(sheetView, "pane");
|
|
265
|
+
if (pane && pane.attrs["state"] === "frozen") {
|
|
266
|
+
const ySplit = parseInt(pane.attrs["ySplit"] ?? "0", 10);
|
|
267
|
+
const xSplit = parseInt(pane.attrs["xSplit"] ?? "0", 10);
|
|
268
|
+
if (ySplit > 0)
|
|
269
|
+
freezeRows = ySplit;
|
|
270
|
+
if (xSplit > 0)
|
|
271
|
+
freezeColumns = xSplit;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
// Merge cells
|
|
276
|
+
const mergeCellsEl = findLocal(root, "mergeCells");
|
|
277
|
+
if (mergeCellsEl) {
|
|
278
|
+
for (const mc of findLocals(mergeCellsEl, "mergeCell")) {
|
|
279
|
+
const ref = mc.attrs["ref"];
|
|
280
|
+
if (!ref || !ref.includes(":"))
|
|
281
|
+
continue;
|
|
282
|
+
const m = parseMergeRef(ref);
|
|
283
|
+
merges.set(`${m.startCol}:${m.startRow}`, {
|
|
284
|
+
colSpan: m.colSpan,
|
|
285
|
+
rowSpan: m.rowSpan,
|
|
286
|
+
});
|
|
287
|
+
// Mark covered cells
|
|
288
|
+
for (let r = m.startRow; r < m.startRow + m.rowSpan; r++) {
|
|
289
|
+
for (let c = m.startCol; c < m.startCol + m.colSpan; c++) {
|
|
290
|
+
if (r === m.startRow && c === m.startCol)
|
|
291
|
+
continue; // skip primary
|
|
292
|
+
coveredCells.add(`${c}:${r}`);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Sheet data
|
|
298
|
+
const sheetData = findLocal(root, "sheetData");
|
|
299
|
+
if (!sheetData)
|
|
300
|
+
return { name: "", rows, merges, coveredCells, freezeRows, freezeColumns };
|
|
301
|
+
for (const rowEl of findLocals(sheetData, "row")) {
|
|
302
|
+
const rowAttr = rowEl.attrs["r"];
|
|
303
|
+
if (!rowAttr)
|
|
304
|
+
continue;
|
|
305
|
+
const rowIdx = parseInt(rowAttr, 10) - 1;
|
|
306
|
+
const cells = new Map();
|
|
307
|
+
for (const cellEl of findLocals(rowEl, "c")) {
|
|
308
|
+
const cellRef = cellEl.attrs["r"];
|
|
309
|
+
if (!cellRef)
|
|
310
|
+
continue;
|
|
311
|
+
let colIdx;
|
|
312
|
+
try {
|
|
313
|
+
colIdx = parseCellRef(cellRef).col;
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
continue;
|
|
317
|
+
}
|
|
318
|
+
const t = cellEl.attrs["t"] ?? "n"; // type attribute
|
|
319
|
+
const s = parseInt(cellEl.attrs["s"] ?? "-1", 10); // style index
|
|
320
|
+
const vEl = findLocal(cellEl, "v");
|
|
321
|
+
const fEl = findLocal(cellEl, "f");
|
|
322
|
+
const isEl = findLocal(cellEl, "is"); // inline string
|
|
323
|
+
const rawValue = vEl ? textContent(vEl) : null;
|
|
324
|
+
const formulaStr = fEl ? textContent(fEl) : undefined;
|
|
325
|
+
let cell;
|
|
326
|
+
if (t === "s" && rawValue !== null) {
|
|
327
|
+
// Shared string
|
|
328
|
+
const idx = parseInt(rawValue, 10);
|
|
329
|
+
cell = {
|
|
330
|
+
type: "string",
|
|
331
|
+
value: sharedStrings[idx] ?? "",
|
|
332
|
+
formula: formulaStr,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
else if (t === "b") {
|
|
336
|
+
// Boolean
|
|
337
|
+
cell = {
|
|
338
|
+
type: "boolean",
|
|
339
|
+
value: rawValue === "1",
|
|
340
|
+
formula: formulaStr,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
else if (t === "str") {
|
|
344
|
+
// Formula result string
|
|
345
|
+
cell = {
|
|
346
|
+
type: "formula",
|
|
347
|
+
value: rawValue ?? "",
|
|
348
|
+
formula: formulaStr,
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
else if (t === "inlineStr" && isEl) {
|
|
352
|
+
// Inline string
|
|
353
|
+
const tEl = findLocal(isEl, "t");
|
|
354
|
+
cell = {
|
|
355
|
+
type: "string",
|
|
356
|
+
value: tEl ? textContent(tEl) : "",
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
else if (t === "e") {
|
|
360
|
+
// Error
|
|
361
|
+
cell = {
|
|
362
|
+
type: "error",
|
|
363
|
+
value: rawValue ?? "#ERROR!",
|
|
364
|
+
formula: formulaStr,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
// Number, date, or formula with numeric result
|
|
369
|
+
if (rawValue === null) {
|
|
370
|
+
cell = { type: "empty", value: null };
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
const num = parseFloat(rawValue);
|
|
374
|
+
const isDate = s >= 0 && isDateStyle(s, styles.cellXfs, styles.customFormats);
|
|
375
|
+
if (formulaStr) {
|
|
376
|
+
cell = {
|
|
377
|
+
type: "formula",
|
|
378
|
+
value: isDate ? xlsxSerialToDate(num) : num,
|
|
379
|
+
formula: formulaStr,
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
else if (isDate) {
|
|
383
|
+
cell = { type: "date", value: xlsxSerialToDate(num) };
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
cell = { type: "number", value: num };
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
cells.set(colIdx, cell);
|
|
391
|
+
}
|
|
392
|
+
if (cells.size > 0) {
|
|
393
|
+
rows.set(rowIdx, { cells });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
catch {
|
|
398
|
+
// Malformed sheet XML — return what we have
|
|
399
|
+
}
|
|
400
|
+
return { name: "", rows, merges, coveredCells, freezeRows, freezeColumns };
|
|
401
|
+
}
|
|
402
|
+
// ─── Public API ───────────────────────────────────────────────────────
|
|
403
|
+
/**
|
|
404
|
+
* Parse an XLSX file into an intermediate XlsxWorkbook model.
|
|
405
|
+
*
|
|
406
|
+
* @param bytes - Raw .xlsx file bytes (Uint8Array or ArrayBuffer).
|
|
407
|
+
* @returns XlsxWorkbook with typed cell values.
|
|
408
|
+
*/
|
|
409
|
+
export function readXlsx(bytes) {
|
|
410
|
+
const data = bytes instanceof ArrayBuffer ? new Uint8Array(bytes) : bytes;
|
|
411
|
+
const files = unzipSync(data);
|
|
412
|
+
const decode = (path) => {
|
|
413
|
+
const entry = files[path];
|
|
414
|
+
return entry ? strFromU8(entry) : null;
|
|
415
|
+
};
|
|
416
|
+
// Shared strings (optional)
|
|
417
|
+
const sharedStrings = (() => {
|
|
418
|
+
const xml = decode("xl/sharedStrings.xml");
|
|
419
|
+
return xml ? parseSharedStrings(xml) : [];
|
|
420
|
+
})();
|
|
421
|
+
// Styles (optional but needed for date detection)
|
|
422
|
+
const styles = (() => {
|
|
423
|
+
const xml = decode("xl/styles.xml");
|
|
424
|
+
return xml ? parseStyles(xml) : { cellXfs: [], customFormats: new Map() };
|
|
425
|
+
})();
|
|
426
|
+
// Workbook — sheet list
|
|
427
|
+
const workbookXml = decode("xl/workbook.xml");
|
|
428
|
+
if (!workbookXml)
|
|
429
|
+
return { sheets: [] };
|
|
430
|
+
const sheetRefs = parseWorkbook(workbookXml);
|
|
431
|
+
// Relationships — rId → file path
|
|
432
|
+
const relsXml = decode("xl/_rels/workbook.xml.rels");
|
|
433
|
+
const relsMap = relsXml ? parseWorkbookRels(relsXml) : new Map();
|
|
434
|
+
// Parse each sheet
|
|
435
|
+
const sheets = [];
|
|
436
|
+
for (const ref of sheetRefs) {
|
|
437
|
+
const path = relsMap.get(ref.rId);
|
|
438
|
+
if (!path)
|
|
439
|
+
continue;
|
|
440
|
+
const sheetXml = decode(path);
|
|
441
|
+
if (!sheetXml)
|
|
442
|
+
continue;
|
|
443
|
+
const sheet = parseSheet(sheetXml, sharedStrings, styles);
|
|
444
|
+
sheet.name = ref.name;
|
|
445
|
+
sheets.push(sheet);
|
|
446
|
+
}
|
|
447
|
+
return { sheets };
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/xlsx/reader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "odf-kit",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.9",
|
|
4
4
|
"description": "Generate, fill, read, and convert OpenDocument Format (.odt) files in JavaScript and TypeScript. Works in Node.js and browsers.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -26,6 +26,10 @@
|
|
|
26
26
|
"types": "./dist/ods-reader/index.d.ts",
|
|
27
27
|
"import": "./dist/ods-reader/index.js"
|
|
28
28
|
},
|
|
29
|
+
"./xlsx": {
|
|
30
|
+
"types": "./dist/xlsx/index.d.ts",
|
|
31
|
+
"import": "./dist/xlsx/index.js"
|
|
32
|
+
},
|
|
29
33
|
"./template": {
|
|
30
34
|
"types": "./dist/template/index.d.ts",
|
|
31
35
|
"import": "./dist/template/index.js"
|