ooxml.js 2.12.2 → 2.13.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/README.md +2 -2
- package/dist/typed/xlsx/comments.cjs +139 -0
- package/dist/typed/xlsx/comments.d.cts +11 -0
- package/dist/typed/xlsx/comments.d.ts +11 -0
- package/dist/typed/xlsx/comments.js +138 -0
- package/dist/typed/xlsx/content.cjs +25 -1
- package/dist/typed/xlsx/content.js +25 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -106,7 +106,7 @@ const doc = readDocx(decodePackage(bytes));
|
|
|
106
106
|
// inside tables); each run already carries its cascade-resolved bold/italic/colour/font.
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
-
`readXlsx` is the lossy, cell-values-only view. `readXlsxContent`/`buildXlsxPackage` are a separate `ContentDocument`-shaped pair — a richer reader (column widths, row heights, hidden rows/columns, merged ranges, every cell value kind, print settings) matched with this package's first writer, round-tripping a spreadsheet through the same `ContentDocument` shape `documents.js`/`odf.js` use:
|
|
109
|
+
`readXlsx` is the lossy, cell-values-only view. `readXlsxContent`/`buildXlsxPackage` are a separate `ContentDocument`-shaped pair — a richer reader (column widths, row heights, hidden rows/columns, merged ranges, every cell value kind, cell comments, print settings) matched with this package's first writer, round-tripping a spreadsheet through the same `ContentDocument` shape `documents.js`/`odf.js` use:
|
|
110
110
|
|
|
111
111
|
```ts
|
|
112
112
|
import { buildXlsxPackage, decodePackage, readXlsxContent } from 'ooxml.js';
|
|
@@ -229,7 +229,7 @@ The package layers a lossless core outward to lossy convenience views:
|
|
|
229
229
|
- **`src/codec.ts`** — public round-trip surface: `packageCodec`/`xmlCodec` (`z.codec()` pairs) plus `decodePackage`/`encodePackage` wrappers.
|
|
230
230
|
- **`src/compact.ts`** — the ooxml.js format: `compactCodec`/`compactPackageCodec` plus `toCompact`/`fromCompact`/`decodeCompactPackage`/`encodeCompactPackage` wrappers.
|
|
231
231
|
- **`src/typed/`** — one-way, lossy projections. `readDocx` resolves the full style cascade (`docDefaults` → `basedOn` → paragraph-mark → character styles → direct formatting) into ordered `sections` plus comments/footnotes/headers/footers/numbering; `readPptx` resolves placeholder → layout → master → theme inheritance into `slides` (presentation order via `p:sldIdLst`); `readXlsx` covers cell values/formulas, merged ranges, defined names. `typed/shared/` holds shared OOXML primitives (`drawingml.ts` geometry/theme/colour, `color.ts` `ColorTransform` cascade, `units.ts`, `metadata.ts`, `source-path.ts`). Types come from `document-schema.js`. None encodes back to a `Package` — round-trip goes through `decodePackage`/`encodePackage` (see `src/typed/xlsx/` for the one write-back exception).
|
|
232
|
-
- **`src/typed/xlsx/`** — a `ContentDocument`-shaped read/write pair alongside the lossy `readXlsx` (both exported; different callers). `readXlsxContent` reads column widths, row heights, hidden rows/columns, merged ranges, every cell value kind, print settings; `buildXlsxPackage` builds a complete xlsx `Package` from scratch (never editing the decoded package). `number-format.ts`/`styles.ts`/`serial.ts` run both ways: reading classifies style index → format code → kind (`percentage`/`currency`/`date`/`time`/`dateTime`); writing emits interned `numFmt` codes, fed back through the classifier in tests. The classifier is not a formatter (`displayText` is the typed-value spelling). Scope limits: `currency` with no ISO code writes as plain `number`; non-canonical temporal values degrade to text.
|
|
232
|
+
- **`src/typed/xlsx/`** — a `ContentDocument`-shaped read/write pair alongside the lossy `readXlsx` (both exported; different callers). `readXlsxContent` reads column widths, row heights, hidden rows/columns, merged ranges, every cell value kind, print settings, and cell comments (`comments.ts`: legacy `xl/comments{N}.xml` notes plus `[MS-XLSX]` threaded comments, both resolved through the worksheet part's own relationships, never by part name); `buildXlsxPackage` builds a complete xlsx `Package` from scratch (never editing the decoded package). `number-format.ts`/`styles.ts`/`serial.ts` run both ways: reading classifies style index → format code → kind (`percentage`/`currency`/`date`/`time`/`dateTime`); writing emits interned `numFmt` codes, fed back through the classifier in tests. The classifier is not a formatter (`displayText` is the typed-value spelling). Scope limits: `currency` with no ISO code writes as plain `number`; non-canonical temporal values degrade to text; cell comments read but do not write (`buildXlsxPackage` emits no comment part, so they do not survive this pair).
|
|
233
233
|
|
|
234
234
|
## Conventions
|
|
235
235
|
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
const require_typed_util = require("../util.cjs");
|
|
3
|
+
let document_schema_js = require("document-schema.js");
|
|
4
|
+
//#region src/typed/xlsx/comments.ts
|
|
5
|
+
const REL_COMMENTS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
|
|
6
|
+
const REL_THREADED_COMMENTS = "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment";
|
|
7
|
+
const REL_PERSON = "http://schemas.microsoft.com/office/2017/10/relationships/person";
|
|
8
|
+
function localName(tag) {
|
|
9
|
+
const colon = tag.lastIndexOf(":");
|
|
10
|
+
return colon === -1 ? tag : tag.slice(colon + 1);
|
|
11
|
+
}
|
|
12
|
+
function childrenWithLocalName(element, local) {
|
|
13
|
+
const out = [];
|
|
14
|
+
for (const child of element.children) if (child.type === "element" && localName(child.tag) === local) out.push(child);
|
|
15
|
+
return out;
|
|
16
|
+
}
|
|
17
|
+
function normalizeGuid(value) {
|
|
18
|
+
return value.replaceAll("{", "").replaceAll("}", "").toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
function relatedPartPaths(pkg, partPath, relType) {
|
|
21
|
+
const paths = [];
|
|
22
|
+
for (const rel of require_typed_util.resolveRelationships(pkg, partPath).values()) if (rel.type === relType) paths.push(rel.target);
|
|
23
|
+
return paths;
|
|
24
|
+
}
|
|
25
|
+
function readLegacyCommentText(text) {
|
|
26
|
+
let value = "";
|
|
27
|
+
for (const t of require_typed_util.elementsWithTag(text.children, "t")) value += require_typed_util.textContent(t);
|
|
28
|
+
return value === "" ? require_typed_util.textContent(text) : value;
|
|
29
|
+
}
|
|
30
|
+
function readLegacyComments(pkg, sheetPath, into) {
|
|
31
|
+
for (const path of relatedPartPaths(pkg, sheetPath, REL_COMMENTS)) {
|
|
32
|
+
const root = require_typed_util.rootElement(pkg.parts[path]);
|
|
33
|
+
if (root === void 0) continue;
|
|
34
|
+
const authorsEl = require_typed_util.childrenWithTag(root, "authors")[0];
|
|
35
|
+
const authors = authorsEl === void 0 ? [] : require_typed_util.childrenWithTag(authorsEl, "author").map(require_typed_util.textContent);
|
|
36
|
+
const commentList = require_typed_util.childrenWithTag(root, "commentList")[0];
|
|
37
|
+
if (commentList === void 0) continue;
|
|
38
|
+
for (const comment of require_typed_util.childrenWithTag(commentList, "comment")) {
|
|
39
|
+
const ref = require_typed_util.attr(comment, "ref");
|
|
40
|
+
const position = ref === void 0 ? void 0 : (0, document_schema_js.parseCellReference)(ref);
|
|
41
|
+
const textEl = require_typed_util.childrenWithTag(comment, "text")[0];
|
|
42
|
+
if (position === void 0 || textEl === void 0) continue;
|
|
43
|
+
const entry = { text: readLegacyCommentText(textEl) };
|
|
44
|
+
const authorIdRaw = require_typed_util.attr(comment, "authorId");
|
|
45
|
+
const authorIndex = authorIdRaw === void 0 ? void 0 : Number.parseInt(authorIdRaw, 10);
|
|
46
|
+
const author = authorIndex === void 0 ? void 0 : authors[authorIndex];
|
|
47
|
+
if (author !== void 0) entry.author = author;
|
|
48
|
+
into.set(`${position.row}:${position.column}`, {
|
|
49
|
+
row: position.row,
|
|
50
|
+
column: position.column,
|
|
51
|
+
comment: entry
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function readPersons(pkg, sheetPath) {
|
|
57
|
+
const persons = /* @__PURE__ */ new Map();
|
|
58
|
+
for (const path of relatedPartPaths(pkg, sheetPath, REL_PERSON)) {
|
|
59
|
+
const root = require_typed_util.rootElement(pkg.parts[path]);
|
|
60
|
+
if (root === void 0) continue;
|
|
61
|
+
for (const person of childrenWithLocalName(root, "person")) {
|
|
62
|
+
const id = require_typed_util.attr(person, "id");
|
|
63
|
+
const displayName = require_typed_util.attr(person, "displayName");
|
|
64
|
+
if (id !== void 0 && displayName !== void 0) persons.set(normalizeGuid(id), displayName);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return persons;
|
|
68
|
+
}
|
|
69
|
+
function readThreadedAuthor(element, persons) {
|
|
70
|
+
const displayName = require_typed_util.attr(element, "displayName");
|
|
71
|
+
if (displayName !== void 0) return displayName;
|
|
72
|
+
const personId = require_typed_util.attr(element, "personId");
|
|
73
|
+
return personId === void 0 ? void 0 : persons.get(normalizeGuid(personId));
|
|
74
|
+
}
|
|
75
|
+
function readThreadedCreatedAt(element) {
|
|
76
|
+
const dT = require_typed_util.attr(element, "dT");
|
|
77
|
+
if (dT !== void 0) return dT;
|
|
78
|
+
const dCreation = require_typed_util.attr(element, "dCreation");
|
|
79
|
+
if (dCreation === void 0) return;
|
|
80
|
+
const ms = Number(dCreation);
|
|
81
|
+
return Number.isFinite(ms) ? new Date(ms).toISOString() : void 0;
|
|
82
|
+
}
|
|
83
|
+
function readThreadedComments(pkg, sheetPath, into) {
|
|
84
|
+
const partPaths = relatedPartPaths(pkg, sheetPath, REL_THREADED_COMMENTS);
|
|
85
|
+
if (partPaths.length === 0) return;
|
|
86
|
+
const persons = readPersons(pkg, sheetPath);
|
|
87
|
+
for (const path of partPaths) {
|
|
88
|
+
const root = require_typed_util.rootElement(pkg.parts[path]);
|
|
89
|
+
if (root === void 0) continue;
|
|
90
|
+
const groups = /* @__PURE__ */ new Map();
|
|
91
|
+
for (const element of childrenWithLocalName(root, "threadedComment")) {
|
|
92
|
+
const ref = require_typed_util.attr(element, "ref");
|
|
93
|
+
const position = ref === void 0 ? void 0 : (0, document_schema_js.parseCellReference)(ref);
|
|
94
|
+
const textEl = childrenWithLocalName(element, "text")[0];
|
|
95
|
+
if (position === void 0 || textEl === void 0) continue;
|
|
96
|
+
const entry = {
|
|
97
|
+
row: position.row,
|
|
98
|
+
column: position.column,
|
|
99
|
+
text: require_typed_util.textContent(textEl)
|
|
100
|
+
};
|
|
101
|
+
const author = readThreadedAuthor(element, persons);
|
|
102
|
+
if (author !== void 0) entry.author = author;
|
|
103
|
+
const createdAt = readThreadedCreatedAt(element);
|
|
104
|
+
if (createdAt !== void 0) entry.createdAt = createdAt;
|
|
105
|
+
const parentId = require_typed_util.attr(element, "parentId") ?? require_typed_util.attr(element, "parent");
|
|
106
|
+
if (parentId !== void 0) entry.parentId = parentId;
|
|
107
|
+
const key = `${position.row}:${position.column}`;
|
|
108
|
+
const group = groups.get(key);
|
|
109
|
+
if (group === void 0) groups.set(key, [entry]);
|
|
110
|
+
else group.push(entry);
|
|
111
|
+
}
|
|
112
|
+
for (const [key, group] of groups) {
|
|
113
|
+
const rootEntry = group.find((entry) => entry.parentId === void 0) ?? group.at(0);
|
|
114
|
+
if (rootEntry === void 0) continue;
|
|
115
|
+
const comment = { text: rootEntry.text };
|
|
116
|
+
if (rootEntry.author !== void 0) comment.author = rootEntry.author;
|
|
117
|
+
if (rootEntry.createdAt !== void 0) comment.createdAt = rootEntry.createdAt;
|
|
118
|
+
const replies = group.filter((entry) => entry !== rootEntry);
|
|
119
|
+
if (replies.length > 0) comment.replies = replies.map((reply) => {
|
|
120
|
+
const answer = { text: reply.text };
|
|
121
|
+
if (reply.author !== void 0) answer.author = reply.author;
|
|
122
|
+
return answer;
|
|
123
|
+
});
|
|
124
|
+
into.set(key, {
|
|
125
|
+
row: rootEntry.row,
|
|
126
|
+
column: rootEntry.column,
|
|
127
|
+
comment
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
function readSheetCellComments(pkg, sheetPath) {
|
|
133
|
+
const comments = /* @__PURE__ */ new Map();
|
|
134
|
+
readLegacyComments(pkg, sheetPath, comments);
|
|
135
|
+
readThreadedComments(pkg, sheetPath, comments);
|
|
136
|
+
return comments;
|
|
137
|
+
}
|
|
138
|
+
//#endregion
|
|
139
|
+
exports.readSheetCellComments = readSheetCellComments;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { r as Package } from "../../package-L24lkba-.cjs";
|
|
2
|
+
import { ContentSheetCellComment } from "document-schema.js";
|
|
3
|
+
//#region src/typed/xlsx/comments.d.ts
|
|
4
|
+
interface SheetCellComment {
|
|
5
|
+
row: number;
|
|
6
|
+
column: number;
|
|
7
|
+
comment: ContentSheetCellComment;
|
|
8
|
+
}
|
|
9
|
+
declare function readSheetCellComments(pkg: Package, sheetPath: string): Map<string, SheetCellComment>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { SheetCellComment, readSheetCellComments };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { r as Package } from "../../package-BUojjTXf.js";
|
|
2
|
+
import { ContentSheetCellComment } from "document-schema.js";
|
|
3
|
+
//#region src/typed/xlsx/comments.d.ts
|
|
4
|
+
interface SheetCellComment {
|
|
5
|
+
row: number;
|
|
6
|
+
column: number;
|
|
7
|
+
comment: ContentSheetCellComment;
|
|
8
|
+
}
|
|
9
|
+
declare function readSheetCellComments(pkg: Package, sheetPath: string): Map<string, SheetCellComment>;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { SheetCellComment, readSheetCellComments };
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { attr, childrenWithTag, elementsWithTag, resolveRelationships, rootElement, textContent } from "../util.js";
|
|
2
|
+
import { parseCellReference } from "document-schema.js";
|
|
3
|
+
//#region src/typed/xlsx/comments.ts
|
|
4
|
+
const REL_COMMENTS = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
|
|
5
|
+
const REL_THREADED_COMMENTS = "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment";
|
|
6
|
+
const REL_PERSON = "http://schemas.microsoft.com/office/2017/10/relationships/person";
|
|
7
|
+
function localName(tag) {
|
|
8
|
+
const colon = tag.lastIndexOf(":");
|
|
9
|
+
return colon === -1 ? tag : tag.slice(colon + 1);
|
|
10
|
+
}
|
|
11
|
+
function childrenWithLocalName(element, local) {
|
|
12
|
+
const out = [];
|
|
13
|
+
for (const child of element.children) if (child.type === "element" && localName(child.tag) === local) out.push(child);
|
|
14
|
+
return out;
|
|
15
|
+
}
|
|
16
|
+
function normalizeGuid(value) {
|
|
17
|
+
return value.replaceAll("{", "").replaceAll("}", "").toLowerCase();
|
|
18
|
+
}
|
|
19
|
+
function relatedPartPaths(pkg, partPath, relType) {
|
|
20
|
+
const paths = [];
|
|
21
|
+
for (const rel of resolveRelationships(pkg, partPath).values()) if (rel.type === relType) paths.push(rel.target);
|
|
22
|
+
return paths;
|
|
23
|
+
}
|
|
24
|
+
function readLegacyCommentText(text) {
|
|
25
|
+
let value = "";
|
|
26
|
+
for (const t of elementsWithTag(text.children, "t")) value += textContent(t);
|
|
27
|
+
return value === "" ? textContent(text) : value;
|
|
28
|
+
}
|
|
29
|
+
function readLegacyComments(pkg, sheetPath, into) {
|
|
30
|
+
for (const path of relatedPartPaths(pkg, sheetPath, REL_COMMENTS)) {
|
|
31
|
+
const root = rootElement(pkg.parts[path]);
|
|
32
|
+
if (root === void 0) continue;
|
|
33
|
+
const authorsEl = childrenWithTag(root, "authors")[0];
|
|
34
|
+
const authors = authorsEl === void 0 ? [] : childrenWithTag(authorsEl, "author").map(textContent);
|
|
35
|
+
const commentList = childrenWithTag(root, "commentList")[0];
|
|
36
|
+
if (commentList === void 0) continue;
|
|
37
|
+
for (const comment of childrenWithTag(commentList, "comment")) {
|
|
38
|
+
const ref = attr(comment, "ref");
|
|
39
|
+
const position = ref === void 0 ? void 0 : parseCellReference(ref);
|
|
40
|
+
const textEl = childrenWithTag(comment, "text")[0];
|
|
41
|
+
if (position === void 0 || textEl === void 0) continue;
|
|
42
|
+
const entry = { text: readLegacyCommentText(textEl) };
|
|
43
|
+
const authorIdRaw = attr(comment, "authorId");
|
|
44
|
+
const authorIndex = authorIdRaw === void 0 ? void 0 : Number.parseInt(authorIdRaw, 10);
|
|
45
|
+
const author = authorIndex === void 0 ? void 0 : authors[authorIndex];
|
|
46
|
+
if (author !== void 0) entry.author = author;
|
|
47
|
+
into.set(`${position.row}:${position.column}`, {
|
|
48
|
+
row: position.row,
|
|
49
|
+
column: position.column,
|
|
50
|
+
comment: entry
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function readPersons(pkg, sheetPath) {
|
|
56
|
+
const persons = /* @__PURE__ */ new Map();
|
|
57
|
+
for (const path of relatedPartPaths(pkg, sheetPath, REL_PERSON)) {
|
|
58
|
+
const root = rootElement(pkg.parts[path]);
|
|
59
|
+
if (root === void 0) continue;
|
|
60
|
+
for (const person of childrenWithLocalName(root, "person")) {
|
|
61
|
+
const id = attr(person, "id");
|
|
62
|
+
const displayName = attr(person, "displayName");
|
|
63
|
+
if (id !== void 0 && displayName !== void 0) persons.set(normalizeGuid(id), displayName);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return persons;
|
|
67
|
+
}
|
|
68
|
+
function readThreadedAuthor(element, persons) {
|
|
69
|
+
const displayName = attr(element, "displayName");
|
|
70
|
+
if (displayName !== void 0) return displayName;
|
|
71
|
+
const personId = attr(element, "personId");
|
|
72
|
+
return personId === void 0 ? void 0 : persons.get(normalizeGuid(personId));
|
|
73
|
+
}
|
|
74
|
+
function readThreadedCreatedAt(element) {
|
|
75
|
+
const dT = attr(element, "dT");
|
|
76
|
+
if (dT !== void 0) return dT;
|
|
77
|
+
const dCreation = attr(element, "dCreation");
|
|
78
|
+
if (dCreation === void 0) return;
|
|
79
|
+
const ms = Number(dCreation);
|
|
80
|
+
return Number.isFinite(ms) ? new Date(ms).toISOString() : void 0;
|
|
81
|
+
}
|
|
82
|
+
function readThreadedComments(pkg, sheetPath, into) {
|
|
83
|
+
const partPaths = relatedPartPaths(pkg, sheetPath, REL_THREADED_COMMENTS);
|
|
84
|
+
if (partPaths.length === 0) return;
|
|
85
|
+
const persons = readPersons(pkg, sheetPath);
|
|
86
|
+
for (const path of partPaths) {
|
|
87
|
+
const root = rootElement(pkg.parts[path]);
|
|
88
|
+
if (root === void 0) continue;
|
|
89
|
+
const groups = /* @__PURE__ */ new Map();
|
|
90
|
+
for (const element of childrenWithLocalName(root, "threadedComment")) {
|
|
91
|
+
const ref = attr(element, "ref");
|
|
92
|
+
const position = ref === void 0 ? void 0 : parseCellReference(ref);
|
|
93
|
+
const textEl = childrenWithLocalName(element, "text")[0];
|
|
94
|
+
if (position === void 0 || textEl === void 0) continue;
|
|
95
|
+
const entry = {
|
|
96
|
+
row: position.row,
|
|
97
|
+
column: position.column,
|
|
98
|
+
text: textContent(textEl)
|
|
99
|
+
};
|
|
100
|
+
const author = readThreadedAuthor(element, persons);
|
|
101
|
+
if (author !== void 0) entry.author = author;
|
|
102
|
+
const createdAt = readThreadedCreatedAt(element);
|
|
103
|
+
if (createdAt !== void 0) entry.createdAt = createdAt;
|
|
104
|
+
const parentId = attr(element, "parentId") ?? attr(element, "parent");
|
|
105
|
+
if (parentId !== void 0) entry.parentId = parentId;
|
|
106
|
+
const key = `${position.row}:${position.column}`;
|
|
107
|
+
const group = groups.get(key);
|
|
108
|
+
if (group === void 0) groups.set(key, [entry]);
|
|
109
|
+
else group.push(entry);
|
|
110
|
+
}
|
|
111
|
+
for (const [key, group] of groups) {
|
|
112
|
+
const rootEntry = group.find((entry) => entry.parentId === void 0) ?? group.at(0);
|
|
113
|
+
if (rootEntry === void 0) continue;
|
|
114
|
+
const comment = { text: rootEntry.text };
|
|
115
|
+
if (rootEntry.author !== void 0) comment.author = rootEntry.author;
|
|
116
|
+
if (rootEntry.createdAt !== void 0) comment.createdAt = rootEntry.createdAt;
|
|
117
|
+
const replies = group.filter((entry) => entry !== rootEntry);
|
|
118
|
+
if (replies.length > 0) comment.replies = replies.map((reply) => {
|
|
119
|
+
const answer = { text: reply.text };
|
|
120
|
+
if (reply.author !== void 0) answer.author = reply.author;
|
|
121
|
+
return answer;
|
|
122
|
+
});
|
|
123
|
+
into.set(key, {
|
|
124
|
+
row: rootEntry.row,
|
|
125
|
+
column: rootEntry.column,
|
|
126
|
+
comment
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
function readSheetCellComments(pkg, sheetPath) {
|
|
132
|
+
const comments = /* @__PURE__ */ new Map();
|
|
133
|
+
readLegacyComments(pkg, sheetPath, comments);
|
|
134
|
+
readThreadedComments(pkg, sheetPath, comments);
|
|
135
|
+
return comments;
|
|
136
|
+
}
|
|
137
|
+
//#endregion
|
|
138
|
+
export { readSheetCellComments };
|
|
@@ -8,6 +8,7 @@ const require_typed_xlsx_util = require("./util.cjs");
|
|
|
8
8
|
const require_typed_xlsx_print_settings = require("./print-settings.cjs");
|
|
9
9
|
const require_typed_xlsx_serial = require("./serial.cjs");
|
|
10
10
|
const require_typed_xlsx_styles = require("./styles.cjs");
|
|
11
|
+
const require_typed_xlsx_comments = require("./comments.cjs");
|
|
11
12
|
const require_typed_xlsx_units = require("./units.cjs");
|
|
12
13
|
let document_schema_js = require("document-schema.js");
|
|
13
14
|
//#region src/typed/xlsx/content.ts
|
|
@@ -296,6 +297,27 @@ function readCells(worksheet, sharedStrings, context) {
|
|
|
296
297
|
applyMergedRanges(worksheet, cells);
|
|
297
298
|
return cells;
|
|
298
299
|
}
|
|
300
|
+
function applyCellComments(comments, cells) {
|
|
301
|
+
if (comments.size === 0) return;
|
|
302
|
+
const byPosition = /* @__PURE__ */ new Map();
|
|
303
|
+
for (const cell of cells) byPosition.set(`${cell.row}:${cell.column}`, cell);
|
|
304
|
+
for (const [key, { row, column, comment }] of comments) {
|
|
305
|
+
const existing = byPosition.get(key);
|
|
306
|
+
if (existing !== void 0) {
|
|
307
|
+
existing.comment = comment;
|
|
308
|
+
continue;
|
|
309
|
+
}
|
|
310
|
+
const materialised = {
|
|
311
|
+
row,
|
|
312
|
+
column,
|
|
313
|
+
value: { kind: "empty" },
|
|
314
|
+
displayText: "",
|
|
315
|
+
comment
|
|
316
|
+
};
|
|
317
|
+
cells.push(materialised);
|
|
318
|
+
byPosition.set(key, materialised);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
299
321
|
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context) {
|
|
300
322
|
const worksheet = require_typed_util.rootElement(pkg.parts[entry.path]);
|
|
301
323
|
if (worksheet === void 0) return {
|
|
@@ -306,9 +328,11 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, c
|
|
|
306
328
|
images: [],
|
|
307
329
|
printSettings: require_typed_xlsx_print_settings.readPrintSettings(fallbackEmptyWorksheet(), sheetIndex, definedNamesBySheet)
|
|
308
330
|
};
|
|
331
|
+
const cells = readCells(worksheet, sharedStrings, context);
|
|
332
|
+
applyCellComments(require_typed_xlsx_comments.readSheetCellComments(pkg, entry.path), cells);
|
|
309
333
|
return {
|
|
310
334
|
name: entry.name,
|
|
311
|
-
cells
|
|
335
|
+
cells,
|
|
312
336
|
columns: readColumns(worksheet),
|
|
313
337
|
rows: readRows(worksheet),
|
|
314
338
|
images: [],
|
|
@@ -7,6 +7,7 @@ import { readXmlBool } from "./util.js";
|
|
|
7
7
|
import { readPrintSettings } from "./print-settings.js";
|
|
8
8
|
import { readDate1904, serialToIsoDate, serialToIsoDateTime, serialToIsoTime } from "./serial.js";
|
|
9
9
|
import { readCellStyles } from "./styles.js";
|
|
10
|
+
import { readSheetCellComments } from "./comments.js";
|
|
10
11
|
import { columnWidthCharsToPt } from "./units.js";
|
|
11
12
|
import { CONTENT_FORMAT_VERSION, parseCellReference, parseRangeReference } from "document-schema.js";
|
|
12
13
|
//#region src/typed/xlsx/content.ts
|
|
@@ -295,6 +296,27 @@ function readCells(worksheet, sharedStrings, context) {
|
|
|
295
296
|
applyMergedRanges(worksheet, cells);
|
|
296
297
|
return cells;
|
|
297
298
|
}
|
|
299
|
+
function applyCellComments(comments, cells) {
|
|
300
|
+
if (comments.size === 0) return;
|
|
301
|
+
const byPosition = /* @__PURE__ */ new Map();
|
|
302
|
+
for (const cell of cells) byPosition.set(`${cell.row}:${cell.column}`, cell);
|
|
303
|
+
for (const [key, { row, column, comment }] of comments) {
|
|
304
|
+
const existing = byPosition.get(key);
|
|
305
|
+
if (existing !== void 0) {
|
|
306
|
+
existing.comment = comment;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
const materialised = {
|
|
310
|
+
row,
|
|
311
|
+
column,
|
|
312
|
+
value: { kind: "empty" },
|
|
313
|
+
displayText: "",
|
|
314
|
+
comment
|
|
315
|
+
};
|
|
316
|
+
cells.push(materialised);
|
|
317
|
+
byPosition.set(key, materialised);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
298
320
|
function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, context) {
|
|
299
321
|
const worksheet = rootElement(pkg.parts[entry.path]);
|
|
300
322
|
if (worksheet === void 0) return {
|
|
@@ -305,9 +327,11 @@ function readSheet(pkg, entry, sheetIndex, sharedStrings, definedNamesBySheet, c
|
|
|
305
327
|
images: [],
|
|
306
328
|
printSettings: readPrintSettings(fallbackEmptyWorksheet(), sheetIndex, definedNamesBySheet)
|
|
307
329
|
};
|
|
330
|
+
const cells = readCells(worksheet, sharedStrings, context);
|
|
331
|
+
applyCellComments(readSheetCellComments(pkg, entry.path), cells);
|
|
308
332
|
return {
|
|
309
333
|
name: entry.name,
|
|
310
|
-
cells
|
|
334
|
+
cells,
|
|
311
335
|
columns: readColumns(worksheet),
|
|
312
336
|
rows: readRows(worksheet),
|
|
313
337
|
images: [],
|
package/package.json
CHANGED