@cj-tech-master/excelts 9.5.0 → 9.5.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 (68) hide show
  1. package/dist/browser/modules/pdf/excel-bridge.js +27 -1
  2. package/dist/browser/modules/pdf/render/layout-engine.js +74 -9
  3. package/dist/browser/modules/pdf/render/style-converter.d.ts +1 -1
  4. package/dist/browser/modules/pdf/render/style-converter.js +98 -1
  5. package/dist/browser/modules/pdf/types.d.ts +1 -0
  6. package/dist/browser/modules/word/color-utils.d.ts +18 -0
  7. package/dist/browser/modules/word/color-utils.js +94 -0
  8. package/dist/browser/modules/word/content-types.d.ts +15 -15
  9. package/dist/browser/modules/word/content-types.js +39 -43
  10. package/dist/browser/modules/word/crypto.d.ts +17 -0
  11. package/dist/browser/modules/word/crypto.js +18 -0
  12. package/dist/browser/modules/word/document-io.d.ts +58 -0
  13. package/dist/browser/modules/word/document-io.js +239 -0
  14. package/dist/browser/modules/word/document.d.ts +64 -135
  15. package/dist/browser/modules/word/document.js +207 -469
  16. package/dist/browser/modules/word/docx-packager.js +90 -90
  17. package/dist/browser/modules/word/html-renderer.js +1 -1
  18. package/dist/browser/modules/word/html.d.ts +13 -0
  19. package/dist/browser/modules/word/html.js +12 -0
  20. package/dist/browser/modules/word/index.base.d.ts +6 -9
  21. package/dist/browser/modules/word/index.base.js +7 -10
  22. package/dist/browser/modules/word/namespaces.d.ts +159 -0
  23. package/dist/browser/modules/word/namespaces.js +189 -0
  24. package/dist/browser/modules/word/relationships.d.ts +15 -16
  25. package/dist/browser/modules/word/relationships.js +37 -45
  26. package/dist/cjs/modules/pdf/excel-bridge.js +27 -1
  27. package/dist/cjs/modules/pdf/render/layout-engine.js +74 -9
  28. package/dist/cjs/modules/pdf/render/style-converter.js +98 -1
  29. package/dist/cjs/modules/word/color-utils.js +97 -0
  30. package/dist/cjs/modules/word/content-types.js +44 -45
  31. package/dist/cjs/modules/word/crypto.js +34 -0
  32. package/dist/cjs/modules/word/document-io.js +244 -0
  33. package/dist/cjs/modules/word/document.js +209 -473
  34. package/dist/cjs/modules/word/docx-packager.js +88 -88
  35. package/dist/cjs/modules/word/html-renderer.js +2 -2
  36. package/dist/cjs/modules/word/html.js +16 -0
  37. package/dist/cjs/modules/word/index.base.js +17 -27
  38. package/dist/cjs/modules/word/namespaces.js +192 -0
  39. package/dist/cjs/modules/word/relationships.js +42 -47
  40. package/dist/esm/modules/pdf/excel-bridge.js +27 -1
  41. package/dist/esm/modules/pdf/render/layout-engine.js +74 -9
  42. package/dist/esm/modules/pdf/render/style-converter.js +98 -1
  43. package/dist/esm/modules/word/color-utils.js +94 -0
  44. package/dist/esm/modules/word/content-types.js +39 -43
  45. package/dist/esm/modules/word/crypto.js +18 -0
  46. package/dist/esm/modules/word/document-io.js +239 -0
  47. package/dist/esm/modules/word/document.js +207 -469
  48. package/dist/esm/modules/word/docx-packager.js +90 -90
  49. package/dist/esm/modules/word/html-renderer.js +1 -1
  50. package/dist/esm/modules/word/html.js +12 -0
  51. package/dist/esm/modules/word/index.base.js +7 -10
  52. package/dist/esm/modules/word/namespaces.js +189 -0
  53. package/dist/esm/modules/word/relationships.js +37 -45
  54. package/dist/iife/excelts.iife.js +153 -11
  55. package/dist/iife/excelts.iife.js.map +1 -1
  56. package/dist/iife/excelts.iife.min.js +4 -4
  57. package/dist/types/modules/pdf/render/style-converter.d.ts +1 -1
  58. package/dist/types/modules/pdf/types.d.ts +1 -0
  59. package/dist/types/modules/word/color-utils.d.ts +18 -0
  60. package/dist/types/modules/word/content-types.d.ts +15 -15
  61. package/dist/types/modules/word/crypto.d.ts +17 -0
  62. package/dist/types/modules/word/document-io.d.ts +58 -0
  63. package/dist/types/modules/word/document.d.ts +64 -135
  64. package/dist/types/modules/word/html.d.ts +13 -0
  65. package/dist/types/modules/word/index.base.d.ts +6 -9
  66. package/dist/types/modules/word/namespaces.d.ts +159 -0
  67. package/dist/types/modules/word/relationships.d.ts +15 -16
  68. package/package.json +1 -1
@@ -0,0 +1,159 @@
1
+ /**
2
+ * DOCX Module — Sub-namespace objects
3
+ *
4
+ * Groups flat builder helpers into logical namespaces for better
5
+ * IDE discoverability. These are re-exports aggregated into objects;
6
+ * since they reference the same underlying functions, tree-shaking
7
+ * still applies at the individual function level for consumers who
8
+ * import the flat named exports instead.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { Run, Paragraph, Table, Math, Field } from "excelts/word";
13
+ *
14
+ * const doc = Document.create();
15
+ * Document.addParagraphElement(doc, Paragraph.create([
16
+ * Run.bold("Hello"),
17
+ * Run.text(" world")
18
+ * ]));
19
+ * ```
20
+ */
21
+ import { text, bold, italic, pageBreak, lineBreak, columnBreak, tab, positionalTab, ruby, carriageReturn, noBreakHyphen, softHyphen, symbol, field, pageNumberField, totalPagesField, sectionPagesField, sectionField, dateField, sequenceField, timeField, authorField, titleField, subjectField, keywordsField, fileNameField, fileSizeField, styleRefField, refField, pageRefField, noteRefField, hyperlinkField, quoteField, tocField, tcField, indexEntryField, indexField, ifField, includeTextField, includePictureField, formTextField, formCheckboxField, formDropdownField, paragraph, textParagraph, heading, hyperlink, bookmarkStart, bookmarkEnd, commentRangeStart, commentRangeEnd, commentReference, insertedRun, deletedRun, movedFromRun, movedToRun, moveFromRangeStart, moveFromRangeEnd, moveToRangeStart, moveToRangeEnd, checkBox, mathBlock, mathRun, mathFraction, mathSqrt, mathRoot, mathSum, mathIntegral, mathProduct, mathSuperScript, mathSubScript, mathSubSuperScript, mathPreSubSuperScript, mathPhantom, mathGroupChar, mathBorderBox, mathDelimiter, mathNary, mathFunction, mathLimit, mathMatrix, mathAccent, mathBar, mathBox, mathEquationArray, floatingImage, drawingShape, chart, structuredDocumentTag, border, gridBorders, cell, row, table, simpleTable, searchText, replaceText, mailMerge, paragraphCount, countWords, getHeadings, findBookmark, findComment, listImages, listTables, listHyperlinks, tableCount, extractText } from "./document.js";
22
+ /** Namespace for creating text runs (inline content). */
23
+ export declare const Run: {
24
+ text: typeof text;
25
+ bold: typeof bold;
26
+ italic: typeof italic;
27
+ pageBreak: typeof pageBreak;
28
+ lineBreak: typeof lineBreak;
29
+ columnBreak: typeof columnBreak;
30
+ tab: typeof tab;
31
+ positionalTab: typeof positionalTab;
32
+ ruby: typeof ruby;
33
+ carriageReturn: typeof carriageReturn;
34
+ noBreakHyphen: typeof noBreakHyphen;
35
+ softHyphen: typeof softHyphen;
36
+ symbol: typeof symbol;
37
+ };
38
+ /** Namespace for creating field codes. */
39
+ export declare const Field: {
40
+ create: typeof field;
41
+ pageNumber: typeof pageNumberField;
42
+ totalPages: typeof totalPagesField;
43
+ sectionPages: typeof sectionPagesField;
44
+ section: typeof sectionField;
45
+ date: typeof dateField;
46
+ sequence: typeof sequenceField;
47
+ time: typeof timeField;
48
+ author: typeof authorField;
49
+ title: typeof titleField;
50
+ subject: typeof subjectField;
51
+ keywords: typeof keywordsField;
52
+ fileName: typeof fileNameField;
53
+ fileSize: typeof fileSizeField;
54
+ styleRef: typeof styleRefField;
55
+ ref: typeof refField;
56
+ pageRef: typeof pageRefField;
57
+ noteRef: typeof noteRefField;
58
+ hyperlink: typeof hyperlinkField;
59
+ quote: typeof quoteField;
60
+ toc: typeof tocField;
61
+ tc: typeof tcField;
62
+ indexEntry: typeof indexEntryField;
63
+ index: typeof indexField;
64
+ condition: typeof ifField;
65
+ includeText: typeof includeTextField;
66
+ includePicture: typeof includePictureField;
67
+ formText: typeof formTextField;
68
+ formCheckbox: typeof formCheckboxField;
69
+ formDropdown: typeof formDropdownField;
70
+ };
71
+ /** Namespace for creating paragraphs. */
72
+ export declare const Paragraph: {
73
+ create: typeof paragraph;
74
+ text: typeof textParagraph;
75
+ heading: typeof heading;
76
+ hyperlink: typeof hyperlink;
77
+ bookmarkStart: typeof bookmarkStart;
78
+ bookmarkEnd: typeof bookmarkEnd;
79
+ };
80
+ /** Namespace for comment-related markers. */
81
+ export declare const Comment: {
82
+ rangeStart: typeof commentRangeStart;
83
+ rangeEnd: typeof commentRangeEnd;
84
+ reference: typeof commentReference;
85
+ };
86
+ /** Namespace for track-changes (revision) markers. */
87
+ export declare const TrackChanges: {
88
+ insertedRun: typeof insertedRun;
89
+ deletedRun: typeof deletedRun;
90
+ movedFromRun: typeof movedFromRun;
91
+ movedToRun: typeof movedToRun;
92
+ moveFromRangeStart: typeof moveFromRangeStart;
93
+ moveFromRangeEnd: typeof moveFromRangeEnd;
94
+ moveToRangeStart: typeof moveToRangeStart;
95
+ moveToRangeEnd: typeof moveToRangeEnd;
96
+ };
97
+ /** Namespace for OMML (Office Math) content. */
98
+ export declare const Math: {
99
+ block: typeof mathBlock;
100
+ run: typeof mathRun;
101
+ fraction: typeof mathFraction;
102
+ sqrt: typeof mathSqrt;
103
+ root: typeof mathRoot;
104
+ sum: typeof mathSum;
105
+ integral: typeof mathIntegral;
106
+ product: typeof mathProduct;
107
+ superScript: typeof mathSuperScript;
108
+ subScript: typeof mathSubScript;
109
+ subSuperScript: typeof mathSubSuperScript;
110
+ preSubSuperScript: typeof mathPreSubSuperScript;
111
+ phantom: typeof mathPhantom;
112
+ groupChar: typeof mathGroupChar;
113
+ borderBox: typeof mathBorderBox;
114
+ delimiter: typeof mathDelimiter;
115
+ nary: typeof mathNary;
116
+ func: typeof mathFunction;
117
+ limit: typeof mathLimit;
118
+ matrix: typeof mathMatrix;
119
+ accent: typeof mathAccent;
120
+ bar: typeof mathBar;
121
+ box: typeof mathBox;
122
+ equationArray: typeof mathEquationArray;
123
+ };
124
+ /** Namespace for creating tables. */
125
+ export declare const Table: {
126
+ create: typeof table;
127
+ simple: typeof simpleTable;
128
+ row: typeof row;
129
+ cell: typeof cell;
130
+ border: typeof border;
131
+ gridBorders: typeof gridBorders;
132
+ };
133
+ /** Namespace for drawings (images, shapes, charts). */
134
+ export declare const Drawing: {
135
+ floatingImage: typeof floatingImage;
136
+ shape: typeof drawingShape;
137
+ chart: typeof chart;
138
+ };
139
+ /** Namespace for structured document tags (content controls). */
140
+ export declare const Sdt: {
141
+ create: typeof structuredDocumentTag;
142
+ checkBox: typeof checkBox;
143
+ };
144
+ /** Namespace for querying/searching document content. */
145
+ export declare const Query: {
146
+ search: typeof searchText;
147
+ replace: typeof replaceText;
148
+ mailMerge: typeof mailMerge;
149
+ paragraphCount: typeof paragraphCount;
150
+ countWords: typeof countWords;
151
+ getHeadings: typeof getHeadings;
152
+ findBookmark: typeof findBookmark;
153
+ findComment: typeof findComment;
154
+ listImages: typeof listImages;
155
+ listTables: typeof listTables;
156
+ listHyperlinks: typeof listHyperlinks;
157
+ tableCount: typeof tableCount;
158
+ extractText: typeof extractText;
159
+ };
@@ -0,0 +1,189 @@
1
+ /**
2
+ * DOCX Module — Sub-namespace objects
3
+ *
4
+ * Groups flat builder helpers into logical namespaces for better
5
+ * IDE discoverability. These are re-exports aggregated into objects;
6
+ * since they reference the same underlying functions, tree-shaking
7
+ * still applies at the individual function level for consumers who
8
+ * import the flat named exports instead.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * import { Run, Paragraph, Table, Math, Field } from "excelts/word";
13
+ *
14
+ * const doc = Document.create();
15
+ * Document.addParagraphElement(doc, Paragraph.create([
16
+ * Run.bold("Hello"),
17
+ * Run.text(" world")
18
+ * ]));
19
+ * ```
20
+ */
21
+ import { text, bold, italic, pageBreak, lineBreak, columnBreak, tab, positionalTab, ruby, carriageReturn, noBreakHyphen, softHyphen, symbol, field, pageNumberField, totalPagesField, sectionPagesField, sectionField, dateField, sequenceField, timeField, authorField, titleField, subjectField, keywordsField, fileNameField, fileSizeField, styleRefField, refField, pageRefField, noteRefField, hyperlinkField, quoteField, tocField, tcField, indexEntryField, indexField, ifField, includeTextField, includePictureField, formTextField, formCheckboxField, formDropdownField, paragraph, textParagraph, heading, hyperlink, bookmarkStart, bookmarkEnd, commentRangeStart, commentRangeEnd, commentReference, insertedRun, deletedRun, movedFromRun, movedToRun, moveFromRangeStart, moveFromRangeEnd, moveToRangeStart, moveToRangeEnd, checkBox, mathBlock, mathRun, mathFraction, mathSqrt, mathRoot, mathSum, mathIntegral, mathProduct, mathSuperScript, mathSubScript, mathSubSuperScript, mathPreSubSuperScript, mathPhantom, mathGroupChar, mathBorderBox, mathDelimiter, mathNary, mathFunction, mathLimit, mathMatrix, mathAccent, mathBar, mathBox, mathEquationArray, floatingImage, drawingShape, chart, structuredDocumentTag, border, gridBorders, cell, row, table, simpleTable, searchText, replaceText, mailMerge, paragraphCount, countWords, getHeadings, findBookmark, findComment, listImages, listTables, listHyperlinks, tableCount, extractText } from "./document.js";
22
+ // =============================================================================
23
+ // Run namespace — text run constructors
24
+ // =============================================================================
25
+ /** Namespace for creating text runs (inline content). */
26
+ export const Run = {
27
+ text,
28
+ bold,
29
+ italic,
30
+ pageBreak,
31
+ lineBreak,
32
+ columnBreak,
33
+ tab,
34
+ positionalTab,
35
+ ruby,
36
+ carriageReturn,
37
+ noBreakHyphen,
38
+ softHyphen,
39
+ symbol
40
+ };
41
+ // =============================================================================
42
+ // Field namespace — field code constructors
43
+ // =============================================================================
44
+ /** Namespace for creating field codes. */
45
+ export const Field = {
46
+ create: field,
47
+ pageNumber: pageNumberField,
48
+ totalPages: totalPagesField,
49
+ sectionPages: sectionPagesField,
50
+ section: sectionField,
51
+ date: dateField,
52
+ sequence: sequenceField,
53
+ time: timeField,
54
+ author: authorField,
55
+ title: titleField,
56
+ subject: subjectField,
57
+ keywords: keywordsField,
58
+ fileName: fileNameField,
59
+ fileSize: fileSizeField,
60
+ styleRef: styleRefField,
61
+ ref: refField,
62
+ pageRef: pageRefField,
63
+ noteRef: noteRefField,
64
+ hyperlink: hyperlinkField,
65
+ quote: quoteField,
66
+ toc: tocField,
67
+ tc: tcField,
68
+ indexEntry: indexEntryField,
69
+ index: indexField,
70
+ condition: ifField,
71
+ includeText: includeTextField,
72
+ includePicture: includePictureField,
73
+ formText: formTextField,
74
+ formCheckbox: formCheckboxField,
75
+ formDropdown: formDropdownField
76
+ };
77
+ // =============================================================================
78
+ // Paragraph namespace — paragraph constructors
79
+ // =============================================================================
80
+ /** Namespace for creating paragraphs. */
81
+ export const Paragraph = {
82
+ create: paragraph,
83
+ text: textParagraph,
84
+ heading,
85
+ hyperlink,
86
+ bookmarkStart,
87
+ bookmarkEnd
88
+ };
89
+ // =============================================================================
90
+ // Comment namespace — comment markers
91
+ // =============================================================================
92
+ /** Namespace for comment-related markers. */
93
+ export const Comment = {
94
+ rangeStart: commentRangeStart,
95
+ rangeEnd: commentRangeEnd,
96
+ reference: commentReference
97
+ };
98
+ // =============================================================================
99
+ // TrackChanges namespace — revision markers
100
+ // =============================================================================
101
+ /** Namespace for track-changes (revision) markers. */
102
+ export const TrackChanges = {
103
+ insertedRun,
104
+ deletedRun,
105
+ movedFromRun,
106
+ movedToRun,
107
+ moveFromRangeStart,
108
+ moveFromRangeEnd,
109
+ moveToRangeStart,
110
+ moveToRangeEnd
111
+ };
112
+ // =============================================================================
113
+ // Math namespace — Office Math constructors
114
+ // =============================================================================
115
+ /** Namespace for OMML (Office Math) content. */
116
+ export const Math = {
117
+ block: mathBlock,
118
+ run: mathRun,
119
+ fraction: mathFraction,
120
+ sqrt: mathSqrt,
121
+ root: mathRoot,
122
+ sum: mathSum,
123
+ integral: mathIntegral,
124
+ product: mathProduct,
125
+ superScript: mathSuperScript,
126
+ subScript: mathSubScript,
127
+ subSuperScript: mathSubSuperScript,
128
+ preSubSuperScript: mathPreSubSuperScript,
129
+ phantom: mathPhantom,
130
+ groupChar: mathGroupChar,
131
+ borderBox: mathBorderBox,
132
+ delimiter: mathDelimiter,
133
+ nary: mathNary,
134
+ func: mathFunction,
135
+ limit: mathLimit,
136
+ matrix: mathMatrix,
137
+ accent: mathAccent,
138
+ bar: mathBar,
139
+ box: mathBox,
140
+ equationArray: mathEquationArray
141
+ };
142
+ // =============================================================================
143
+ // Table namespace — table constructors
144
+ // =============================================================================
145
+ /** Namespace for creating tables. */
146
+ export const Table = {
147
+ create: table,
148
+ simple: simpleTable,
149
+ row,
150
+ cell,
151
+ border,
152
+ gridBorders
153
+ };
154
+ // =============================================================================
155
+ // Drawing namespace — images, shapes, charts
156
+ // =============================================================================
157
+ /** Namespace for drawings (images, shapes, charts). */
158
+ export const Drawing = {
159
+ floatingImage,
160
+ shape: drawingShape,
161
+ chart
162
+ };
163
+ // =============================================================================
164
+ // Sdt namespace — structured document tags
165
+ // =============================================================================
166
+ /** Namespace for structured document tags (content controls). */
167
+ export const Sdt = {
168
+ create: structuredDocumentTag,
169
+ checkBox
170
+ };
171
+ // =============================================================================
172
+ // Query namespace — document query/search functions
173
+ // =============================================================================
174
+ /** Namespace for querying/searching document content. */
175
+ export const Query = {
176
+ search: searchText,
177
+ replace: replaceText,
178
+ mailMerge,
179
+ paragraphCount,
180
+ countWords,
181
+ getHeadings,
182
+ findBookmark,
183
+ findComment,
184
+ listImages,
185
+ listTables,
186
+ listHyperlinks,
187
+ tableCount,
188
+ extractText
189
+ };
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * Manages OPC relationships for the DOCX package.
5
5
  * Generates .rels files for package-level and part-level relationships.
6
+ * Uses a plain data record + free functions for tree-shakeability.
6
7
  */
7
8
  import type { XmlSink } from "../xml/types.js";
8
9
  /** A single OPC relationship. */
@@ -12,20 +13,18 @@ export interface Relationship {
12
13
  readonly target: string;
13
14
  readonly targetMode?: "External";
14
15
  }
15
- /**
16
- * Manages relationships and generates .rels XML.
17
- */
18
- export declare class RelationshipManager {
19
- private readonly _rels;
20
- private _nextId;
21
- /** Add a relationship and return its assigned rId. */
22
- add(type: string, target: string, targetMode?: "External"): string;
23
- /** Add a relationship with a specific ID. */
24
- addWithId(id: string, type: string, target: string, targetMode?: "External"): void;
25
- /** Get all relationships. */
26
- get relationships(): readonly Relationship[];
27
- /** Get the number of relationships. */
28
- get count(): number;
29
- /** Render the relationships XML to a sink. */
30
- render(xml: XmlSink): void;
16
+ /** Internal state for relationships (plain record, not a class). */
17
+ export interface RelationshipsState {
18
+ readonly rels: Relationship[];
19
+ nextId: number;
31
20
  }
21
+ /** Create a new empty RelationshipsState. */
22
+ export declare function createRelationships(): RelationshipsState;
23
+ /** Add a relationship and return its assigned rId. */
24
+ export declare function addRelationship(state: RelationshipsState, type: string, target: string, targetMode?: "External"): string;
25
+ /** Add a relationship with a specific ID. */
26
+ export declare function addRelationshipWithId(state: RelationshipsState, id: string, type: string, target: string, targetMode?: "External"): void;
27
+ /** Get the number of relationships. */
28
+ export declare function getRelationshipCount(state: RelationshipsState): number;
29
+ /** Render the relationships XML to a sink. */
30
+ export declare function renderRelationships(state: RelationshipsState, xml: XmlSink): void;
@@ -3,54 +3,46 @@
3
3
  *
4
4
  * Manages OPC relationships for the DOCX package.
5
5
  * Generates .rels files for package-level and part-level relationships.
6
+ * Uses a plain data record + free functions for tree-shakeability.
6
7
  */
7
8
  import { NS_PKG_RELS, STD_DOC_ATTRIBUTES } from "./constants.js";
8
- /**
9
- * Manages relationships and generates .rels XML.
10
- */
11
- export class RelationshipManager {
12
- constructor() {
13
- this._rels = [];
14
- this._nextId = 1;
15
- }
16
- /** Add a relationship and return its assigned rId. */
17
- add(type, target, targetMode) {
18
- const id = `rId${this._nextId++}`;
19
- this._rels.push({ id, type, target, targetMode });
20
- return id;
21
- }
22
- /** Add a relationship with a specific ID. */
23
- addWithId(id, type, target, targetMode) {
24
- this._rels.push({ id, type, target, targetMode });
25
- // Keep nextId above any manually-assigned IDs
26
- const num = parseInt(id.replace("rId", ""), 10);
27
- if (!isNaN(num) && num >= this._nextId) {
28
- this._nextId = num + 1;
29
- }
30
- }
31
- /** Get all relationships. */
32
- get relationships() {
33
- return this._rels;
34
- }
35
- /** Get the number of relationships. */
36
- get count() {
37
- return this._rels.length;
9
+ /** Create a new empty RelationshipsState. */
10
+ export function createRelationships() {
11
+ return { rels: [], nextId: 1 };
12
+ }
13
+ /** Add a relationship and return its assigned rId. */
14
+ export function addRelationship(state, type, target, targetMode) {
15
+ const id = `rId${state.nextId++}`;
16
+ state.rels.push({ id, type, target, targetMode });
17
+ return id;
18
+ }
19
+ /** Add a relationship with a specific ID. */
20
+ export function addRelationshipWithId(state, id, type, target, targetMode) {
21
+ state.rels.push({ id, type, target, targetMode });
22
+ // Keep nextId above any manually-assigned IDs
23
+ const num = parseInt(id.replace("rId", ""), 10);
24
+ if (!isNaN(num) && num >= state.nextId) {
25
+ state.nextId = num + 1;
38
26
  }
39
- /** Render the relationships XML to a sink. */
40
- render(xml) {
41
- xml.openXml(STD_DOC_ATTRIBUTES);
42
- xml.openNode("Relationships", { xmlns: NS_PKG_RELS });
43
- for (const rel of this._rels) {
44
- const attrs = {
45
- Id: rel.id,
46
- Type: rel.type,
47
- Target: rel.target
48
- };
49
- if (rel.targetMode) {
50
- attrs.TargetMode = rel.targetMode;
51
- }
52
- xml.leafNode("Relationship", attrs);
27
+ }
28
+ /** Get the number of relationships. */
29
+ export function getRelationshipCount(state) {
30
+ return state.rels.length;
31
+ }
32
+ /** Render the relationships XML to a sink. */
33
+ export function renderRelationships(state, xml) {
34
+ xml.openXml(STD_DOC_ATTRIBUTES);
35
+ xml.openNode("Relationships", { xmlns: NS_PKG_RELS });
36
+ for (const rel of state.rels) {
37
+ const attrs = {
38
+ Id: rel.id,
39
+ Type: rel.type,
40
+ Target: rel.target
41
+ };
42
+ if (rel.targetMode) {
43
+ attrs.TargetMode = rel.targetMode;
53
44
  }
54
- xml.closeNode();
45
+ xml.leafNode("Relationship", attrs);
55
46
  }
47
+ xml.closeNode();
56
48
  }
@@ -191,6 +191,31 @@ async function convertSheet(ws, workbook) {
191
191
  right: dimensions.model.right
192
192
  }
193
193
  : { top: 0, left: 0, bottom: 0, right: 0 };
194
+ // Expand bounds to include cells that only have styles (borders, fills, fonts)
195
+ // but no values — these are not tracked by dimensions.
196
+ if (hasData) {
197
+ for (let r = bounds.top; r <= bounds.bottom; r++) {
198
+ const row = ws.findRow(r);
199
+ if (!row) {
200
+ continue;
201
+ }
202
+ row.eachCell({ includeEmpty: true }, cell => {
203
+ if (cell.col > bounds.right) {
204
+ const hasStyle = cell.style &&
205
+ ((cell.style.border &&
206
+ (cell.style.border.top ||
207
+ cell.style.border.right ||
208
+ cell.style.border.bottom ||
209
+ cell.style.border.left)) ||
210
+ cell.style.fill ||
211
+ cell.style.font);
212
+ if (hasStyle || (cell.type !== enums_1.ValueType.Null && cell.type !== enums_1.ValueType.Merge)) {
213
+ bounds.right = cell.col;
214
+ }
215
+ }
216
+ });
217
+ }
218
+ }
194
219
  // Convert columns
195
220
  const columns = new Map();
196
221
  if (hasData) {
@@ -484,7 +509,8 @@ function convertColor(color) {
484
509
  return {
485
510
  argb: color.argb,
486
511
  theme: color.theme,
487
- tint: color.tint
512
+ tint: color.tint,
513
+ indexed: color.indexed
488
514
  };
489
515
  }
490
516
  function convertFill(fill) {
@@ -558,7 +558,7 @@ function countWrapLines(cell, fontSize, scaleFactor, sheet, fontManager, options
558
558
  if (value && typeof value === "object" && "richText" in value) {
559
559
  const runs = value.richText;
560
560
  if (runs.length > 0) {
561
- const wrappedCount = countRichTextWrapLines(text, runs, scaleFactor, effectiveWidth, fontManager, options);
561
+ const wrappedCount = countRichTextWrapLines(text, runs, scaleFactor, effectiveWidth, fontManager, options, cell.style?.font);
562
562
  return Math.max(lineCount, wrappedCount);
563
563
  }
564
564
  }
@@ -578,7 +578,10 @@ function countWrapLines(cell, fontSize, scaleFactor, sheet, fontManager, options
578
578
  * This mirrors the logic in wrapRichTextLines (page-renderer) so that
579
579
  * the row height calculation matches the actual rendering.
580
580
  */
581
- function countRichTextWrapLines(text, runs, scaleFactor, effectiveWidth, fontManager, options) {
581
+ function countRichTextWrapLines(text, runs, scaleFactor, effectiveWidth, fontManager, options, cellFont) {
582
+ // Use cell-level font as fallback for runs without their own font
583
+ const defaultFamily = cellFont?.name ?? options.defaultFontFamily;
584
+ const defaultSize = cellFont?.size ?? options.defaultFontSize;
582
585
  // Build character-to-run mapping
583
586
  const runForChar = [];
584
587
  for (let ri = 0; ri < runs.length; ri++) {
@@ -586,9 +589,20 @@ function countRichTextWrapLines(text, runs, scaleFactor, effectiveWidth, fontMan
586
589
  runForChar.push(ri);
587
590
  }
588
591
  }
589
- // Resolve font resources for each run
592
+ // Resolve font resources for each run (with cell font inheritance)
590
593
  const runResources = runs.map(run => {
591
- const fontProps = (0, style_converter_1.extractFontProperties)(run.font, options.defaultFontFamily, options.defaultFontSize);
594
+ const effectiveRunFont = run.font
595
+ ? {
596
+ name: run.font.name ?? cellFont?.name,
597
+ size: run.font.size ?? cellFont?.size,
598
+ bold: run.font.bold ?? cellFont?.bold,
599
+ italic: run.font.italic ?? cellFont?.italic,
600
+ strike: run.font.strike ?? cellFont?.strike,
601
+ underline: run.font.underline ?? cellFont?.underline,
602
+ color: run.font.color ?? cellFont?.color
603
+ }
604
+ : cellFont;
605
+ const fontProps = (0, style_converter_1.extractFontProperties)(effectiveRunFont, defaultFamily, defaultSize);
592
606
  const pdfFontName = (0, font_manager_1.resolvePdfFontName)(fontProps.fontFamily, fontProps.bold, fontProps.italic);
593
607
  return fontManager.hasEmbeddedFont()
594
608
  ? fontManager.getEmbeddedResourceName()
@@ -596,7 +610,15 @@ function countRichTextWrapLines(text, runs, scaleFactor, effectiveWidth, fontMan
596
610
  });
597
611
  // Resolve scaled font sizes for each run
598
612
  const runFontSizes = runs.map(run => {
599
- const fontProps = (0, style_converter_1.extractFontProperties)(run.font, options.defaultFontFamily, options.defaultFontSize);
613
+ const effectiveRunFont = run.font
614
+ ? {
615
+ name: run.font.name ?? cellFont?.name,
616
+ size: run.font.size ?? cellFont?.size,
617
+ bold: run.font.bold ?? cellFont?.bold,
618
+ italic: run.font.italic ?? cellFont?.italic
619
+ }
620
+ : cellFont;
621
+ const fontProps = (0, style_converter_1.extractFontProperties)(effectiveRunFont, defaultFamily, defaultSize);
600
622
  return fontProps.fontSize * scaleFactor;
601
623
  });
602
624
  // Measure a range of fullText using per-character run font sizes
@@ -868,8 +890,10 @@ function buildLayoutCell(cell, x, y, width, height, colSpan, rowSpan, options, f
868
890
  // Track non-WinAnsi code points for Type3 fallback font generation
869
891
  fontManager.trackText(text);
870
892
  }
871
- // Rich text runs
872
- const richText = buildRichTextRuns(cell, options, fontManager, scaleFactor);
893
+ // Rich text runs — pass cell-level font as the fallback for runs without
894
+ // their own font definition (e.g. the first run often has no font object
895
+ // and should inherit the cell's style font including bold/italic).
896
+ const richText = buildRichTextRuns(cell, options, fontManager, scaleFactor, style.font);
873
897
  const borders = (0, style_converter_1.excelBordersToPdf)(style.border);
874
898
  return {
875
899
  text,
@@ -1312,6 +1336,30 @@ function computeTextOverflows(cellGrid, rowPage, colGroup, visibleRows, visibleC
1312
1336
  }
1313
1337
  if (overflowAvailable > 0) {
1314
1338
  cell.textOverflowWidth = Math.min(overflowNeeded, overflowAvailable);
1339
+ // Hide internal vertical borders in the overflow region.
1340
+ // In Excel, when text overflows into adjacent empty cells, the shared
1341
+ // vertical borders between them are not drawn (the text appears to
1342
+ // span across seamlessly). We suppress:
1343
+ // - The overflowing cell's right border
1344
+ // - Each covered neighbor's left border (and right border if fully covered)
1345
+ let accumulated = 0;
1346
+ const actualOverflow = cell.textOverflowWidth;
1347
+ // Remove the source cell's right border if text overflows
1348
+ cell.borders.right = null;
1349
+ for (let j = gci + 1; j < colGroup.length; j++) {
1350
+ const neighborCell = cellGrid.get(`${ri}:${j}`);
1351
+ if (!neighborCell) {
1352
+ break;
1353
+ }
1354
+ // Remove the neighbor's left border (shared edge with previous cell)
1355
+ neighborCell.borders.left = null;
1356
+ accumulated += groupColWidths[j];
1357
+ if (accumulated >= actualOverflow) {
1358
+ break;
1359
+ }
1360
+ // If fully covered, also remove the neighbor's right border
1361
+ neighborCell.borders.right = null;
1362
+ }
1315
1363
  }
1316
1364
  }
1317
1365
  }
@@ -1323,7 +1371,7 @@ function computeTextOverflows(cellGrid, rowPage, colGroup, visibleRows, visibleC
1323
1371
  * Build rich text runs from a RichText cell.
1324
1372
  * Returns null for non-RichText cells.
1325
1373
  */
1326
- function buildRichTextRuns(cell, options, fontManager, scaleFactor) {
1374
+ function buildRichTextRuns(cell, options, fontManager, scaleFactor, cellFont) {
1327
1375
  if (!cell || cell.type !== types_1.PdfCellType.RichText) {
1328
1376
  return null;
1329
1377
  }
@@ -1335,8 +1383,25 @@ function buildRichTextRuns(cell, options, fontManager, scaleFactor) {
1335
1383
  if (runs.length === 0) {
1336
1384
  return null;
1337
1385
  }
1386
+ // Use cell-level font as fallback for runs without their own font,
1387
+ // falling back to global defaults only if cell font is not available.
1388
+ const defaultFamily = cellFont?.name ?? options.defaultFontFamily;
1389
+ const defaultSize = cellFont?.size ?? options.defaultFontSize;
1338
1390
  return runs.map(run => {
1339
- const fontProps = (0, style_converter_1.extractFontProperties)(run.font, options.defaultFontFamily, options.defaultFontSize);
1391
+ // When a run has no font at all, use cell font entirely.
1392
+ // When a run has a partial font, merge with cell font for missing properties.
1393
+ const effectiveFont = run.font
1394
+ ? {
1395
+ name: run.font.name ?? cellFont?.name,
1396
+ size: run.font.size ?? cellFont?.size,
1397
+ bold: run.font.bold ?? cellFont?.bold,
1398
+ italic: run.font.italic ?? cellFont?.italic,
1399
+ strike: run.font.strike ?? cellFont?.strike,
1400
+ underline: run.font.underline ?? cellFont?.underline,
1401
+ color: run.font.color ?? cellFont?.color
1402
+ }
1403
+ : cellFont;
1404
+ const fontProps = (0, style_converter_1.extractFontProperties)(effectiveFont, defaultFamily, defaultSize);
1340
1405
  // Register font for this run
1341
1406
  if (fontManager.hasEmbeddedFont()) {
1342
1407
  fontManager.trackText(run.text);