@cj-tech-master/excelts 6.1.0 → 6.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/browser/modules/csv/worker/worker-script.generated.d.ts +1 -1
  2. package/dist/browser/modules/csv/worker/worker-script.generated.js +1 -1
  3. package/dist/browser/modules/excel/stream/sheet-rels-writer.d.ts +2 -1
  4. package/dist/browser/modules/excel/stream/sheet-rels-writer.js +10 -1
  5. package/dist/browser/modules/excel/stream/workbook-writer.browser.js +2 -1
  6. package/dist/browser/modules/excel/stream/worksheet-reader.d.ts +2 -1
  7. package/dist/browser/modules/excel/stream/worksheet-reader.js +4 -1
  8. package/dist/browser/modules/excel/workbook.browser.js +2 -1
  9. package/dist/browser/modules/excel/worksheet.js +2 -1
  10. package/dist/browser/modules/excel/xlsx/xform/sheet/hyperlink-xform.d.ts +8 -3
  11. package/dist/browser/modules/excel/xlsx/xform/sheet/hyperlink-xform.js +20 -10
  12. package/dist/browser/modules/excel/xlsx/xform/sheet/worksheet-xform.js +11 -1
  13. package/dist/cjs/modules/csv/worker/worker-script.generated.js +1 -1
  14. package/dist/cjs/modules/excel/stream/sheet-rels-writer.js +10 -1
  15. package/dist/cjs/modules/excel/stream/workbook-writer.browser.js +2 -1
  16. package/dist/cjs/modules/excel/stream/worksheet-reader.js +4 -1
  17. package/dist/cjs/modules/excel/workbook.browser.js +2 -1
  18. package/dist/cjs/modules/excel/worksheet.js +2 -1
  19. package/dist/cjs/modules/excel/xlsx/xform/sheet/hyperlink-xform.js +20 -9
  20. package/dist/cjs/modules/excel/xlsx/xform/sheet/worksheet-xform.js +11 -1
  21. package/dist/esm/modules/csv/worker/worker-script.generated.js +1 -1
  22. package/dist/esm/modules/excel/stream/sheet-rels-writer.js +10 -1
  23. package/dist/esm/modules/excel/stream/workbook-writer.browser.js +2 -1
  24. package/dist/esm/modules/excel/stream/worksheet-reader.js +4 -1
  25. package/dist/esm/modules/excel/workbook.browser.js +2 -1
  26. package/dist/esm/modules/excel/worksheet.js +2 -1
  27. package/dist/esm/modules/excel/xlsx/xform/sheet/hyperlink-xform.js +20 -10
  28. package/dist/esm/modules/excel/xlsx/xform/sheet/worksheet-xform.js +11 -1
  29. package/dist/iife/excelts.iife.js +77 -72
  30. package/dist/iife/excelts.iife.js.map +1 -1
  31. package/dist/iife/excelts.iife.min.js +34 -34
  32. package/dist/types/modules/csv/worker/worker-script.generated.d.ts +1 -1
  33. package/dist/types/modules/excel/stream/sheet-rels-writer.d.ts +2 -1
  34. package/dist/types/modules/excel/stream/worksheet-reader.d.ts +2 -1
  35. package/dist/types/modules/excel/xlsx/xform/sheet/hyperlink-xform.d.ts +8 -3
  36. package/package.json +13 -13
@@ -227,9 +227,12 @@ class WorksheetReader extends EventEmitter {
227
227
  break;
228
228
  case "hyperlink":
229
229
  if (inHyperlinks) {
230
+ const loc = node.attributes.location;
230
231
  const hyperlink = {
231
232
  ref: node.attributes.ref,
232
- rId: node.attributes["r:id"]
233
+ rId: node.attributes["r:id"],
234
+ // Internal links: resolve target from location attribute
235
+ target: loc ? (loc.startsWith("#") ? loc : `#${loc}`) : undefined
233
236
  };
234
237
  if (emitHyperlinks) {
235
238
  (worksheetEvents || (worksheetEvents = [])).push({ eventType: "hyperlink", value: hyperlink });
@@ -666,7 +666,8 @@ class Workbook {
666
666
  return this._worksheets[id];
667
667
  }
668
668
  if (typeof id === "string") {
669
- return this._worksheets.find(worksheet => worksheet && worksheet.name === id);
669
+ const idLower = id.toLowerCase();
670
+ return this._worksheets.find(worksheet => worksheet && worksheet.name.toLowerCase() === idLower);
670
671
  }
671
672
  return undefined;
672
673
  }
@@ -138,7 +138,8 @@ class Worksheet {
138
138
  }
139
139
  name = name.substring(0, 31);
140
140
  }
141
- if (this._workbook.worksheets.find(ws => ws && ws.name.toLowerCase() === name.toLowerCase())) {
141
+ const nameLower = name.toLowerCase();
142
+ if (this._workbook.worksheets.find(ws => ws && ws !== this && ws.name.toLowerCase() === nameLower)) {
142
143
  throw new WorksheetNameError(`Worksheet name already exists: ${name}`);
143
144
  }
144
145
  this._name = name;
@@ -1,7 +1,7 @@
1
1
  import { BaseXform } from "../base-xform.js";
2
2
  interface HyperlinkModel {
3
3
  address: string;
4
- rId: string;
4
+ rId?: string;
5
5
  tooltip?: string;
6
6
  target?: string;
7
7
  }
@@ -11,6 +11,11 @@ declare class HyperlinkXform extends BaseXform {
11
11
  parseOpen(node: any): boolean;
12
12
  parseText(): void;
13
13
  parseClose(): boolean;
14
- isInternalLink(model: HyperlinkModel): boolean;
15
14
  }
16
- export { HyperlinkXform };
15
+ /**
16
+ * Internal hyperlinks start with "#" (e.g. "#Sheet2!A1").
17
+ * This matches Excel's convention and the OOXML spec where internal links
18
+ * use the `location` attribute instead of a relationship.
19
+ */
20
+ declare function isInternalLink(target: string): boolean;
21
+ export { HyperlinkXform, isInternalLink };
@@ -4,15 +4,17 @@ class HyperlinkXform extends BaseXform {
4
4
  return "hyperlink";
5
5
  }
6
6
  render(xmlStream, model) {
7
- if (this.isInternalLink(model)) {
7
+ if (model.target && isInternalLink(model.target)) {
8
+ // Internal link: use location attribute only (no relationship)
9
+ // Strip the leading "#" — OOXML location attribute is without "#"
8
10
  xmlStream.leafNode("hyperlink", {
9
11
  ref: model.address,
10
- "r:id": model.rId,
11
12
  tooltip: model.tooltip,
12
- location: model.target
13
+ location: model.target.slice(1)
13
14
  });
14
15
  }
15
16
  else {
17
+ // External link: use r:id relationship reference
16
18
  xmlStream.leafNode("hyperlink", {
17
19
  ref: model.address,
18
20
  "r:id": model.rId,
@@ -27,9 +29,13 @@ class HyperlinkXform extends BaseXform {
27
29
  rId: node.attributes["r:id"],
28
30
  tooltip: node.attributes.tooltip
29
31
  };
30
- // This is an internal link
32
+ // Internal link: location attribute stores the target without "#"
33
+ // Normalize: always store as "#Location" in the model regardless of
34
+ // whether the source had a leading "#" (our old buggy output) or not
35
+ // (correct OOXML from Excel or the fixed writer).
31
36
  if (node.attributes.location) {
32
- this.model.target = node.attributes.location;
37
+ const loc = node.attributes.location;
38
+ this.model.target = loc.startsWith("#") ? loc : `#${loc}`;
33
39
  }
34
40
  return true;
35
41
  }
@@ -39,9 +45,13 @@ class HyperlinkXform extends BaseXform {
39
45
  parseClose() {
40
46
  return false;
41
47
  }
42
- isInternalLink(model) {
43
- // @example: Sheet2!D3, return true
44
- return !!(model.target && /^[^!]+![a-zA-Z]+[\d]+$/.test(model.target));
45
- }
46
48
  }
47
- export { HyperlinkXform };
49
+ /**
50
+ * Internal hyperlinks start with "#" (e.g. "#Sheet2!A1").
51
+ * This matches Excel's convention and the OOXML spec where internal links
52
+ * use the `location` attribute instead of a relationship.
53
+ */
54
+ function isInternalLink(target) {
55
+ return target.startsWith("#");
56
+ }
57
+ export { HyperlinkXform, isInternalLink };
@@ -3,11 +3,11 @@ import { XmlStream } from "../../../utils/xml-stream.js";
3
3
  import { RelType } from "../../rel-type.js";
4
4
  import { Merges } from "./merges.js";
5
5
  import { BaseXform } from "../base-xform.js";
6
+ import { isInternalLink, HyperlinkXform } from "./hyperlink-xform.js";
6
7
  import { ListXform } from "../list-xform.js";
7
8
  import { RowXform } from "./row-xform.js";
8
9
  import { ColXform } from "./col-xform.js";
9
10
  import { DimensionXform } from "./dimension-xform.js";
10
- import { HyperlinkXform } from "./hyperlink-xform.js";
11
11
  import { MergeCellXform } from "./merge-cell-xform.js";
12
12
  import { DataValidationsXform } from "./data-validations-xform.js";
13
13
  import { SheetPropertiesXform } from "./sheet-properties-xform.js";
@@ -158,6 +158,11 @@ class WorkSheetXform extends BaseXform {
158
158
  return `rId${r.length + 1}`;
159
159
  }
160
160
  model.hyperlinks.forEach(hyperlink => {
161
+ // Internal links (e.g. "#Sheet2!A1") use the location attribute only,
162
+ // no relationship is needed in the .rels file.
163
+ if (isInternalLink(hyperlink.target)) {
164
+ return;
165
+ }
161
166
  const rId = nextRid(rels);
162
167
  hyperlink.rId = rId;
163
168
  rels.push({
@@ -594,8 +599,13 @@ class WorkSheetXform extends BaseXform {
594
599
  }, {});
595
600
  options.hyperlinkMap = (model.hyperlinks ?? []).reduce((h, hyperlink) => {
596
601
  if (hyperlink.rId) {
602
+ // External link: resolve target from relationship
597
603
  h[hyperlink.address] = rels[hyperlink.rId].Target;
598
604
  }
605
+ else if (hyperlink.target) {
606
+ // Internal link: target was restored from location attribute (with "#" prefix)
607
+ h[hyperlink.address] = hyperlink.target;
608
+ }
599
609
  return h;
600
610
  }, {});
601
611
  options.formulae = {};