@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.
- package/dist/browser/modules/pdf/excel-bridge.js +27 -1
- package/dist/browser/modules/pdf/render/layout-engine.js +74 -9
- package/dist/browser/modules/pdf/render/style-converter.d.ts +1 -1
- package/dist/browser/modules/pdf/render/style-converter.js +98 -1
- package/dist/browser/modules/pdf/types.d.ts +1 -0
- package/dist/browser/modules/word/color-utils.d.ts +18 -0
- package/dist/browser/modules/word/color-utils.js +94 -0
- package/dist/browser/modules/word/content-types.d.ts +15 -15
- package/dist/browser/modules/word/content-types.js +39 -43
- package/dist/browser/modules/word/crypto.d.ts +17 -0
- package/dist/browser/modules/word/crypto.js +18 -0
- package/dist/browser/modules/word/document-io.d.ts +58 -0
- package/dist/browser/modules/word/document-io.js +239 -0
- package/dist/browser/modules/word/document.d.ts +64 -135
- package/dist/browser/modules/word/document.js +207 -469
- package/dist/browser/modules/word/docx-packager.js +90 -90
- package/dist/browser/modules/word/html-renderer.js +1 -1
- package/dist/browser/modules/word/html.d.ts +13 -0
- package/dist/browser/modules/word/html.js +12 -0
- package/dist/browser/modules/word/index.base.d.ts +6 -9
- package/dist/browser/modules/word/index.base.js +7 -10
- package/dist/browser/modules/word/namespaces.d.ts +159 -0
- package/dist/browser/modules/word/namespaces.js +189 -0
- package/dist/browser/modules/word/relationships.d.ts +15 -16
- package/dist/browser/modules/word/relationships.js +37 -45
- package/dist/cjs/modules/pdf/excel-bridge.js +27 -1
- package/dist/cjs/modules/pdf/render/layout-engine.js +74 -9
- package/dist/cjs/modules/pdf/render/style-converter.js +98 -1
- package/dist/cjs/modules/word/color-utils.js +97 -0
- package/dist/cjs/modules/word/content-types.js +44 -45
- package/dist/cjs/modules/word/crypto.js +34 -0
- package/dist/cjs/modules/word/document-io.js +244 -0
- package/dist/cjs/modules/word/document.js +209 -473
- package/dist/cjs/modules/word/docx-packager.js +88 -88
- package/dist/cjs/modules/word/html-renderer.js +2 -2
- package/dist/cjs/modules/word/html.js +16 -0
- package/dist/cjs/modules/word/index.base.js +17 -27
- package/dist/cjs/modules/word/namespaces.js +192 -0
- package/dist/cjs/modules/word/relationships.js +42 -47
- package/dist/esm/modules/pdf/excel-bridge.js +27 -1
- package/dist/esm/modules/pdf/render/layout-engine.js +74 -9
- package/dist/esm/modules/pdf/render/style-converter.js +98 -1
- package/dist/esm/modules/word/color-utils.js +94 -0
- package/dist/esm/modules/word/content-types.js +39 -43
- package/dist/esm/modules/word/crypto.js +18 -0
- package/dist/esm/modules/word/document-io.js +239 -0
- package/dist/esm/modules/word/document.js +207 -469
- package/dist/esm/modules/word/docx-packager.js +90 -90
- package/dist/esm/modules/word/html-renderer.js +1 -1
- package/dist/esm/modules/word/html.js +12 -0
- package/dist/esm/modules/word/index.base.js +7 -10
- package/dist/esm/modules/word/namespaces.js +189 -0
- package/dist/esm/modules/word/relationships.js +37 -45
- package/dist/iife/excelts.iife.js +153 -11
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +4 -4
- package/dist/types/modules/pdf/render/style-converter.d.ts +1 -1
- package/dist/types/modules/pdf/types.d.ts +1 -0
- package/dist/types/modules/word/color-utils.d.ts +18 -0
- package/dist/types/modules/word/content-types.d.ts +15 -15
- package/dist/types/modules/word/crypto.d.ts +17 -0
- package/dist/types/modules/word/document-io.d.ts +58 -0
- package/dist/types/modules/word/document.d.ts +64 -135
- package/dist/types/modules/word/html.d.ts +13 -0
- package/dist/types/modules/word/index.base.d.ts +6 -9
- package/dist/types/modules/word/namespaces.d.ts +159 -0
- package/dist/types/modules/word/relationships.d.ts +15 -16
- package/package.json +1 -1
|
@@ -5,9 +5,12 @@
|
|
|
5
5
|
* High-level fluent API for constructing DOCX documents programmatically.
|
|
6
6
|
* Provides convenience methods for common operations including comments,
|
|
7
7
|
* track changes, TOC, math, text boxes, checkboxes, and custom properties.
|
|
8
|
+
*
|
|
9
|
+
* This file has NO static imports from docx-packager or docx-reader,
|
|
10
|
+
* ensuring that importing builder helpers does not pull in archive/xml code.
|
|
8
11
|
*/
|
|
9
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.
|
|
13
|
+
exports.resolveThemeColor = exports.Document = void 0;
|
|
11
14
|
exports.text = text;
|
|
12
15
|
exports.bold = bold;
|
|
13
16
|
exports.italic = italic;
|
|
@@ -103,7 +106,6 @@ exports.cell = cell;
|
|
|
103
106
|
exports.row = row;
|
|
104
107
|
exports.table = table;
|
|
105
108
|
exports.simpleTable = simpleTable;
|
|
106
|
-
exports.resolveThemeColor = resolveThemeColor;
|
|
107
109
|
exports.paragraphCount = paragraphCount;
|
|
108
110
|
exports.countWords = countWords;
|
|
109
111
|
exports.getHeadings = getHeadings;
|
|
@@ -117,10 +119,6 @@ exports.extractText = extractText;
|
|
|
117
119
|
exports.searchText = searchText;
|
|
118
120
|
exports.replaceText = replaceText;
|
|
119
121
|
exports.mailMerge = mailMerge;
|
|
120
|
-
exports.patchDocument = patchDocument;
|
|
121
|
-
const docx_packager_1 = require("./docx-packager");
|
|
122
|
-
const docx_reader_1 = require("./docx-reader");
|
|
123
|
-
const internal_utils_1 = require("./internal-utils");
|
|
124
122
|
// =============================================================================
|
|
125
123
|
// Helper Builders
|
|
126
124
|
// =============================================================================
|
|
@@ -759,88 +757,91 @@ function simpleTable(data, options) {
|
|
|
759
757
|
borders: opts.borders ? gridBorders() : undefined
|
|
760
758
|
}, opts.columnWidths);
|
|
761
759
|
}
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
760
|
+
/** Cast internal state to opaque handle. */
|
|
761
|
+
function _toHandle(state) {
|
|
762
|
+
return state;
|
|
763
|
+
}
|
|
764
|
+
/** Cast opaque handle back to internal state. */
|
|
765
|
+
function _toState(handle) {
|
|
766
|
+
return handle;
|
|
767
|
+
}
|
|
765
768
|
/**
|
|
766
|
-
*
|
|
769
|
+
* Namespace of free functions for building DOCX documents.
|
|
770
|
+
*
|
|
771
|
+
* Replaces the former `DocumentBuilder` class with tree-shakeable free functions.
|
|
772
|
+
* Each function operates on an opaque `DocumentHandle`.
|
|
767
773
|
*
|
|
768
774
|
* @example
|
|
769
775
|
* ```ts
|
|
770
|
-
* const doc =
|
|
771
|
-
*
|
|
772
|
-
*
|
|
773
|
-
*
|
|
774
|
-
*
|
|
775
|
-
*
|
|
776
|
-
* const bytes = await doc.toBuffer();
|
|
776
|
+
* const doc = Document.create();
|
|
777
|
+
* Document.addHeading(doc, "Hello World", 1);
|
|
778
|
+
* Document.addParagraph(doc, "This is a paragraph.");
|
|
779
|
+
* Document.addTable(doc, [["Name", "Age"], ["Alice", "30"]]);
|
|
780
|
+
* const bytes = await Document.toBuffer(doc);
|
|
777
781
|
* ```
|
|
778
782
|
*/
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
783
|
+
exports.Document = {
|
|
784
|
+
/** Create a new document handle. */
|
|
785
|
+
create() {
|
|
786
|
+
return _toHandle({
|
|
787
|
+
body: [],
|
|
788
|
+
styles: [],
|
|
789
|
+
abstractNumberings: [],
|
|
790
|
+
numberingInstances: [],
|
|
791
|
+
headers: new Map(),
|
|
792
|
+
footers: new Map(),
|
|
793
|
+
footnotes: [],
|
|
794
|
+
endnotes: [],
|
|
795
|
+
images: [],
|
|
796
|
+
fonts: [],
|
|
797
|
+
comments: [],
|
|
798
|
+
customProperties: [],
|
|
799
|
+
nextImageId: 1,
|
|
800
|
+
nextFootnoteId: 1,
|
|
801
|
+
nextEndnoteId: 1,
|
|
802
|
+
nextBookmarkId: 0,
|
|
803
|
+
nextAbstractNumId: 0,
|
|
804
|
+
nextNumId: 1,
|
|
805
|
+
nextDrawingId: 1,
|
|
806
|
+
nextCommentId: 0
|
|
807
|
+
});
|
|
808
|
+
},
|
|
802
809
|
/** Add raw body content. */
|
|
803
|
-
addContent(content) {
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
}
|
|
810
|
+
addContent(doc, content) {
|
|
811
|
+
_toState(doc).body.push(content);
|
|
812
|
+
},
|
|
807
813
|
/** Add a paragraph with runs. */
|
|
808
|
-
addParagraphElement(para) {
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
}
|
|
814
|
+
addParagraphElement(doc, para) {
|
|
815
|
+
_toState(doc).body.push(para);
|
|
816
|
+
},
|
|
812
817
|
/** Add a simple text paragraph. */
|
|
813
|
-
addParagraph(content, properties) {
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
}
|
|
818
|
+
addParagraph(doc, content, properties) {
|
|
819
|
+
_toState(doc).body.push(textParagraph(content, properties));
|
|
820
|
+
},
|
|
817
821
|
/** Add a heading. */
|
|
818
|
-
addHeading(content, level = 1) {
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
}
|
|
822
|
+
addHeading(doc, content, level = 1) {
|
|
823
|
+
_toState(doc).body.push(heading(content, level));
|
|
824
|
+
},
|
|
822
825
|
/** Add a page break. */
|
|
823
|
-
addPageBreak() {
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
}
|
|
826
|
+
addPageBreak(doc) {
|
|
827
|
+
_toState(doc).body.push(paragraph([pageBreak()]));
|
|
828
|
+
},
|
|
827
829
|
/** Add a table from a 2D array. */
|
|
828
|
-
addTable(data, options) {
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
}
|
|
830
|
+
addTable(doc, data, options) {
|
|
831
|
+
_toState(doc).body.push(simpleTable(data, options));
|
|
832
|
+
},
|
|
832
833
|
/** Add a table element. */
|
|
833
|
-
addTableElement(tbl) {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
}
|
|
834
|
+
addTableElement(doc, tbl) {
|
|
835
|
+
_toState(doc).body.push(tbl);
|
|
836
|
+
},
|
|
837
837
|
/** Add an inline image. Returns the image relationship ID and drawing ID. */
|
|
838
|
-
addImage(data, mediaType, width, height, options) {
|
|
839
|
-
const
|
|
840
|
-
const
|
|
841
|
-
const
|
|
842
|
-
|
|
843
|
-
|
|
838
|
+
addImage(doc, data, mediaType, width, height, options) {
|
|
839
|
+
const s = _toState(doc);
|
|
840
|
+
const fileName = `image${s.nextImageId}.${mediaType}`;
|
|
841
|
+
const rId = `__img_${s.nextImageId}`;
|
|
842
|
+
const drawingId = s.nextDrawingId++;
|
|
843
|
+
s.images.push({ data, mediaType, fileName, rId });
|
|
844
|
+
s.body.push(paragraph([
|
|
844
845
|
{
|
|
845
846
|
content: [
|
|
846
847
|
{
|
|
@@ -849,26 +850,27 @@ class DocumentBuilder {
|
|
|
849
850
|
width,
|
|
850
851
|
height,
|
|
851
852
|
altText: options?.altText,
|
|
852
|
-
name: options?.name ?? `Picture ${
|
|
853
|
+
name: options?.name ?? `Picture ${s.nextImageId}`,
|
|
853
854
|
drawingId
|
|
854
855
|
}
|
|
855
856
|
]
|
|
856
857
|
}
|
|
857
858
|
]));
|
|
858
|
-
|
|
859
|
+
s.nextImageId++;
|
|
859
860
|
return { rId, drawingId };
|
|
860
|
-
}
|
|
861
|
+
},
|
|
861
862
|
/** Add a floating image. Returns the image relationship ID. */
|
|
862
|
-
addFloatingImage(data, mediaType, width, height, options) {
|
|
863
|
-
const
|
|
864
|
-
const
|
|
865
|
-
|
|
866
|
-
|
|
863
|
+
addFloatingImage(doc, data, mediaType, width, height, options) {
|
|
864
|
+
const s = _toState(doc);
|
|
865
|
+
const fileName = `image${s.nextImageId}.${mediaType}`;
|
|
866
|
+
const rId = `__img_${s.nextImageId}`;
|
|
867
|
+
s.images.push({ data, mediaType, fileName, rId });
|
|
868
|
+
s.body.push(floatingImage({
|
|
867
869
|
rId,
|
|
868
870
|
width,
|
|
869
871
|
height,
|
|
870
872
|
altText: options?.altText,
|
|
871
|
-
name: options?.name ?? `Picture ${
|
|
873
|
+
name: options?.name ?? `Picture ${s.nextImageId}`,
|
|
872
874
|
horizontalPosition: options?.horizontalPosition,
|
|
873
875
|
verticalPosition: options?.verticalPosition,
|
|
874
876
|
wrap: options?.wrap,
|
|
@@ -884,38 +886,39 @@ class DocumentBuilder {
|
|
|
884
886
|
flipHorizontal: options?.flipHorizontal,
|
|
885
887
|
flipVertical: options?.flipVertical
|
|
886
888
|
}));
|
|
887
|
-
|
|
889
|
+
s.nextImageId++;
|
|
888
890
|
return rId;
|
|
889
|
-
}
|
|
891
|
+
},
|
|
890
892
|
/** Add a custom font definition. */
|
|
891
|
-
addFont(font) {
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
}
|
|
893
|
+
addFont(doc, font) {
|
|
894
|
+
_toState(doc).fonts.push(font);
|
|
895
|
+
},
|
|
895
896
|
/** Set a text watermark on the document. */
|
|
896
|
-
setWatermark(watermark) {
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
}
|
|
897
|
+
setWatermark(doc, watermark) {
|
|
898
|
+
_toState(doc).watermark = watermark;
|
|
899
|
+
},
|
|
900
900
|
/** Add a footnote. Returns the footnote ID. */
|
|
901
|
-
addFootnote(content) {
|
|
902
|
-
const
|
|
901
|
+
addFootnote(doc, content) {
|
|
902
|
+
const s = _toState(doc);
|
|
903
|
+
const id = s.nextFootnoteId++;
|
|
903
904
|
const paras = typeof content === "string" ? [textParagraph(content)] : content;
|
|
904
|
-
|
|
905
|
+
s.footnotes.push({ id, content: paras });
|
|
905
906
|
return id;
|
|
906
|
-
}
|
|
907
|
+
},
|
|
907
908
|
/** Add an endnote. Returns the endnote ID. */
|
|
908
|
-
addEndnote(content) {
|
|
909
|
-
const
|
|
909
|
+
addEndnote(doc, content) {
|
|
910
|
+
const s = _toState(doc);
|
|
911
|
+
const id = s.nextEndnoteId++;
|
|
910
912
|
const paras = typeof content === "string" ? [textParagraph(content)] : content;
|
|
911
|
-
|
|
913
|
+
s.endnotes.push({ id, content: paras });
|
|
912
914
|
return id;
|
|
913
|
-
}
|
|
915
|
+
},
|
|
914
916
|
/** Add a comment. Returns the comment ID. */
|
|
915
|
-
addComment(author, content, options) {
|
|
916
|
-
const
|
|
917
|
+
addComment(doc, author, content, options) {
|
|
918
|
+
const s = _toState(doc);
|
|
919
|
+
const id = s.nextCommentId++;
|
|
917
920
|
const paras = typeof content === "string" ? [textParagraph(content)] : content;
|
|
918
|
-
|
|
921
|
+
s.comments.push({
|
|
919
922
|
id,
|
|
920
923
|
author,
|
|
921
924
|
date: options?.date,
|
|
@@ -923,26 +926,24 @@ class DocumentBuilder {
|
|
|
923
926
|
content: paras
|
|
924
927
|
});
|
|
925
928
|
return id;
|
|
926
|
-
}
|
|
929
|
+
},
|
|
927
930
|
/** Add a Table of Contents. */
|
|
928
|
-
addTableOfContents(options) {
|
|
929
|
-
|
|
931
|
+
addTableOfContents(doc, options) {
|
|
932
|
+
_toState(doc).body.push({
|
|
930
933
|
type: "tableOfContents",
|
|
931
934
|
headingStyleRange: options?.headingStyleRange ?? "1-3",
|
|
932
935
|
hyperlink: options?.hyperlink ?? true,
|
|
933
936
|
...options
|
|
934
937
|
});
|
|
935
|
-
|
|
936
|
-
}
|
|
938
|
+
},
|
|
937
939
|
/** Add a math equation block. */
|
|
938
|
-
addMath(content) {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
}
|
|
940
|
+
addMath(doc, content) {
|
|
941
|
+
_toState(doc).body.push(mathBlock(content));
|
|
942
|
+
},
|
|
942
943
|
/** Add a text box. */
|
|
943
|
-
addTextBox(content, options) {
|
|
944
|
+
addTextBox(doc, content, options) {
|
|
944
945
|
const paras = typeof content === "string" ? [textParagraph(content)] : content;
|
|
945
|
-
|
|
946
|
+
_toState(doc).body.push({
|
|
946
947
|
type: "textBox",
|
|
947
948
|
content: paras,
|
|
948
949
|
width: options?.width,
|
|
@@ -950,15 +951,15 @@ class DocumentBuilder {
|
|
|
950
951
|
stroke: options?.stroke,
|
|
951
952
|
fill: options?.fill
|
|
952
953
|
});
|
|
953
|
-
|
|
954
|
-
}
|
|
954
|
+
},
|
|
955
955
|
/** Add a bullet list. */
|
|
956
|
-
addBulletList(items, level = 0) {
|
|
956
|
+
addBulletList(doc, items, level = 0) {
|
|
957
|
+
const s = _toState(doc);
|
|
957
958
|
// Create abstract numbering for bullets if not exists
|
|
958
|
-
let bulletAbsId =
|
|
959
|
+
let bulletAbsId = s.abstractNumberings.find(a => a.levels[0]?.format === "bullet")?.abstractNumId;
|
|
959
960
|
if (bulletAbsId === undefined) {
|
|
960
|
-
bulletAbsId =
|
|
961
|
-
|
|
961
|
+
bulletAbsId = s.nextAbstractNumId++;
|
|
962
|
+
s.abstractNumberings.push({
|
|
962
963
|
abstractNumId: bulletAbsId,
|
|
963
964
|
multiLevelType: "hybridMultilevel",
|
|
964
965
|
levels: [
|
|
@@ -991,23 +992,23 @@ class DocumentBuilder {
|
|
|
991
992
|
}
|
|
992
993
|
]
|
|
993
994
|
});
|
|
994
|
-
|
|
995
|
-
numId:
|
|
995
|
+
s.numberingInstances.push({
|
|
996
|
+
numId: s.nextNumId++,
|
|
996
997
|
abstractNumId: bulletAbsId
|
|
997
998
|
});
|
|
998
999
|
}
|
|
999
|
-
const numId =
|
|
1000
|
+
const numId = s.numberingInstances.find(n => n.abstractNumId === bulletAbsId).numId;
|
|
1000
1001
|
for (const item of items) {
|
|
1001
|
-
|
|
1002
|
+
s.body.push(textParagraph(item, { numbering: { numId, level } }));
|
|
1002
1003
|
}
|
|
1003
|
-
|
|
1004
|
-
}
|
|
1004
|
+
},
|
|
1005
1005
|
/** Add a numbered list. */
|
|
1006
|
-
addNumberedList(items, level = 0) {
|
|
1007
|
-
|
|
1006
|
+
addNumberedList(doc, items, level = 0) {
|
|
1007
|
+
const s = _toState(doc);
|
|
1008
|
+
let numAbsId = s.abstractNumberings.find(a => a.levels[0]?.format === "decimal")?.abstractNumId;
|
|
1008
1009
|
if (numAbsId === undefined) {
|
|
1009
|
-
numAbsId =
|
|
1010
|
-
|
|
1010
|
+
numAbsId = s.nextAbstractNumId++;
|
|
1011
|
+
s.abstractNumberings.push({
|
|
1011
1012
|
abstractNumId: numAbsId,
|
|
1012
1013
|
multiLevelType: "hybridMultilevel",
|
|
1013
1014
|
levels: [
|
|
@@ -1037,35 +1038,32 @@ class DocumentBuilder {
|
|
|
1037
1038
|
}
|
|
1038
1039
|
]
|
|
1039
1040
|
});
|
|
1040
|
-
|
|
1041
|
-
numId:
|
|
1041
|
+
s.numberingInstances.push({
|
|
1042
|
+
numId: s.nextNumId++,
|
|
1042
1043
|
abstractNumId: numAbsId
|
|
1043
1044
|
});
|
|
1044
1045
|
}
|
|
1045
|
-
const numId =
|
|
1046
|
+
const numId = s.numberingInstances.find(n => n.abstractNumId === numAbsId).numId;
|
|
1046
1047
|
for (const item of items) {
|
|
1047
|
-
|
|
1048
|
+
s.body.push(textParagraph(item, { numbering: { numId, level } }));
|
|
1048
1049
|
}
|
|
1049
|
-
|
|
1050
|
-
}
|
|
1050
|
+
},
|
|
1051
1051
|
/** Set section properties (page size, margins, etc.). */
|
|
1052
|
-
setSectionProperties(props) {
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
}
|
|
1052
|
+
setSectionProperties(doc, props) {
|
|
1053
|
+
_toState(doc).sectionProperties = props;
|
|
1054
|
+
},
|
|
1056
1055
|
/** Set document defaults. */
|
|
1057
|
-
setDocDefaults(defaults) {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
}
|
|
1056
|
+
setDocDefaults(doc, defaults) {
|
|
1057
|
+
_toState(doc).docDefaults = defaults;
|
|
1058
|
+
},
|
|
1061
1059
|
/** Add a style definition. */
|
|
1062
|
-
addStyle(style) {
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
}
|
|
1060
|
+
addStyle(doc, style) {
|
|
1061
|
+
_toState(doc).styles.push(style);
|
|
1062
|
+
},
|
|
1066
1063
|
/** Set default styles (Normal, Heading1-6, Hyperlink, etc.). */
|
|
1067
|
-
useDefaultStyles() {
|
|
1068
|
-
|
|
1064
|
+
useDefaultStyles(doc) {
|
|
1065
|
+
const s = _toState(doc);
|
|
1066
|
+
s.docDefaults = {
|
|
1069
1067
|
runProperties: {
|
|
1070
1068
|
font: { ascii: "Calibri", hAnsi: "Calibri", eastAsia: "SimSun", cs: "Times New Roman" },
|
|
1071
1069
|
size: 22,
|
|
@@ -1076,7 +1074,7 @@ class DocumentBuilder {
|
|
|
1076
1074
|
spacing: { after: 160, line: 259, lineRule: "auto" }
|
|
1077
1075
|
}
|
|
1078
1076
|
};
|
|
1079
|
-
|
|
1077
|
+
s.styles.push({ type: "paragraph", styleId: "Normal", name: "Normal", isDefault: true, qFormat: true }, {
|
|
1080
1078
|
type: "paragraph",
|
|
1081
1079
|
styleId: "Heading1",
|
|
1082
1080
|
name: "heading 1",
|
|
@@ -1124,193 +1122,91 @@ class DocumentBuilder {
|
|
|
1124
1122
|
uiPriority: 39,
|
|
1125
1123
|
tableProperties: { borders: gridBorders(4, "auto") }
|
|
1126
1124
|
});
|
|
1127
|
-
|
|
1128
|
-
}
|
|
1125
|
+
},
|
|
1129
1126
|
/** Set a header for the given type. */
|
|
1130
|
-
setHeader(type, content) {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
}
|
|
1127
|
+
setHeader(doc, type, content) {
|
|
1128
|
+
_toState(doc).headers.set(type, { content });
|
|
1129
|
+
},
|
|
1134
1130
|
/** Set a footer for the given type. */
|
|
1135
|
-
setFooter(type, content) {
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
}
|
|
1131
|
+
setFooter(doc, type, content) {
|
|
1132
|
+
_toState(doc).footers.set(type, { content });
|
|
1133
|
+
},
|
|
1139
1134
|
/** Set document settings. */
|
|
1140
|
-
setSettings(settings) {
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
}
|
|
1135
|
+
setSettings(doc, settings) {
|
|
1136
|
+
_toState(doc).settings = settings;
|
|
1137
|
+
},
|
|
1144
1138
|
/** Set core properties (metadata). */
|
|
1145
|
-
setCoreProperties(props) {
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
}
|
|
1139
|
+
setCoreProperties(doc, props) {
|
|
1140
|
+
_toState(doc).coreProperties = props;
|
|
1141
|
+
},
|
|
1149
1142
|
/** Set application properties. */
|
|
1150
|
-
setAppProperties(props) {
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
}
|
|
1143
|
+
setAppProperties(doc, props) {
|
|
1144
|
+
_toState(doc).appProperties = props;
|
|
1145
|
+
},
|
|
1154
1146
|
/** Set document background. */
|
|
1155
|
-
setBackground(background) {
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
}
|
|
1147
|
+
setBackground(doc, background) {
|
|
1148
|
+
_toState(doc).background = background;
|
|
1149
|
+
},
|
|
1159
1150
|
/** Add a custom document property. */
|
|
1160
|
-
addCustomProperty(name, value) {
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
}
|
|
1151
|
+
addCustomProperty(doc, name, value) {
|
|
1152
|
+
_toState(doc).customProperties.push({ name, value });
|
|
1153
|
+
},
|
|
1164
1154
|
/** Add a section break with properties. */
|
|
1165
|
-
addSectionBreak(props) {
|
|
1155
|
+
addSectionBreak(doc, props) {
|
|
1156
|
+
const s = _toState(doc);
|
|
1166
1157
|
// Insert as the last paragraph's section properties
|
|
1167
|
-
if (
|
|
1168
|
-
const last =
|
|
1158
|
+
if (s.body.length > 0) {
|
|
1159
|
+
const last = s.body[s.body.length - 1];
|
|
1169
1160
|
if (last.type === "paragraph") {
|
|
1170
1161
|
const existingProps = last.properties ?? {};
|
|
1171
|
-
|
|
1162
|
+
s.body[s.body.length - 1] = {
|
|
1172
1163
|
...last,
|
|
1173
1164
|
properties: { ...existingProps, sectionProperties: props }
|
|
1174
1165
|
};
|
|
1175
|
-
return
|
|
1166
|
+
return;
|
|
1176
1167
|
}
|
|
1177
1168
|
}
|
|
1178
1169
|
// If no previous paragraph, add an empty one with section properties
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
}
|
|
1170
|
+
s.body.push(paragraph([], { sectionProperties: props }));
|
|
1171
|
+
},
|
|
1182
1172
|
/** Get next available bookmark ID. */
|
|
1183
|
-
nextBookmarkId() {
|
|
1184
|
-
return
|
|
1185
|
-
}
|
|
1186
|
-
/** Build the DocxDocument model. */
|
|
1187
|
-
build() {
|
|
1173
|
+
nextBookmarkId(doc) {
|
|
1174
|
+
return _toState(doc).nextBookmarkId++;
|
|
1175
|
+
},
|
|
1176
|
+
/** Build the DocxDocument model from the handle. */
|
|
1177
|
+
build(doc) {
|
|
1178
|
+
const s = _toState(doc);
|
|
1188
1179
|
return {
|
|
1189
|
-
body:
|
|
1190
|
-
sectionProperties:
|
|
1180
|
+
body: s.body,
|
|
1181
|
+
sectionProperties: s.sectionProperties ?? {
|
|
1191
1182
|
pageSize: { width: 12240, height: 15840 },
|
|
1192
1183
|
margins: { top: 1440, right: 1440, bottom: 1440, left: 1440 }
|
|
1193
1184
|
},
|
|
1194
|
-
styles:
|
|
1195
|
-
docDefaults:
|
|
1196
|
-
abstractNumberings:
|
|
1197
|
-
numberingInstances:
|
|
1198
|
-
headers:
|
|
1199
|
-
footers:
|
|
1200
|
-
footnotes:
|
|
1201
|
-
endnotes:
|
|
1202
|
-
images:
|
|
1203
|
-
fonts:
|
|
1204
|
-
settings:
|
|
1205
|
-
coreProperties:
|
|
1206
|
-
appProperties:
|
|
1207
|
-
comments:
|
|
1208
|
-
background:
|
|
1209
|
-
customProperties:
|
|
1210
|
-
watermark:
|
|
1185
|
+
styles: s.styles.length > 0 ? s.styles : undefined,
|
|
1186
|
+
docDefaults: s.docDefaults,
|
|
1187
|
+
abstractNumberings: s.abstractNumberings.length > 0 ? s.abstractNumberings : undefined,
|
|
1188
|
+
numberingInstances: s.numberingInstances.length > 0 ? s.numberingInstances : undefined,
|
|
1189
|
+
headers: s.headers.size > 0 ? s.headers : undefined,
|
|
1190
|
+
footers: s.footers.size > 0 ? s.footers : undefined,
|
|
1191
|
+
footnotes: s.footnotes.length > 0 ? s.footnotes : undefined,
|
|
1192
|
+
endnotes: s.endnotes.length > 0 ? s.endnotes : undefined,
|
|
1193
|
+
images: s.images.length > 0 ? s.images : undefined,
|
|
1194
|
+
fonts: s.fonts.length > 0 ? s.fonts : undefined,
|
|
1195
|
+
settings: s.settings,
|
|
1196
|
+
coreProperties: s.coreProperties,
|
|
1197
|
+
appProperties: s.appProperties,
|
|
1198
|
+
comments: s.comments.length > 0 ? s.comments : undefined,
|
|
1199
|
+
background: s.background,
|
|
1200
|
+
customProperties: s.customProperties.length > 0 ? s.customProperties : undefined,
|
|
1201
|
+
watermark: s.watermark
|
|
1211
1202
|
};
|
|
1212
1203
|
}
|
|
1213
|
-
|
|
1214
|
-
async toBuffer(compressionLevel) {
|
|
1215
|
-
return (0, docx_packager_1.packageDocx)(this.build(), compressionLevel);
|
|
1216
|
-
}
|
|
1217
|
-
/** Build and package to base64 string. */
|
|
1218
|
-
async toBase64(compressionLevel) {
|
|
1219
|
-
const bytes = await this.toBuffer(compressionLevel);
|
|
1220
|
-
return (0, internal_utils_1.bytesToBase64)(bytes);
|
|
1221
|
-
}
|
|
1222
|
-
}
|
|
1223
|
-
exports.DocumentBuilder = DocumentBuilder;
|
|
1204
|
+
};
|
|
1224
1205
|
// =============================================================================
|
|
1225
|
-
// Theme Color Resolution
|
|
1206
|
+
// Theme Color Resolution (re-export from color-utils for backward compat)
|
|
1226
1207
|
// =============================================================================
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
* Word uses different names in run/paragraph properties vs the theme XML.
|
|
1230
|
-
*/
|
|
1231
|
-
const THEME_COLOR_MAP = {
|
|
1232
|
-
dark1: "dk1",
|
|
1233
|
-
light1: "lt1",
|
|
1234
|
-
dark2: "dk2",
|
|
1235
|
-
light2: "lt2",
|
|
1236
|
-
accent1: "accent1",
|
|
1237
|
-
accent2: "accent2",
|
|
1238
|
-
accent3: "accent3",
|
|
1239
|
-
accent4: "accent4",
|
|
1240
|
-
accent5: "accent5",
|
|
1241
|
-
accent6: "accent6",
|
|
1242
|
-
hyperlink: "hlink",
|
|
1243
|
-
followedHyperlink: "folHlink",
|
|
1244
|
-
// Direct names also work
|
|
1245
|
-
dk1: "dk1",
|
|
1246
|
-
lt1: "lt1",
|
|
1247
|
-
dk2: "dk2",
|
|
1248
|
-
lt2: "lt2",
|
|
1249
|
-
hlink: "hlink",
|
|
1250
|
-
folHlink: "folHlink"
|
|
1251
|
-
};
|
|
1252
|
-
/**
|
|
1253
|
-
* Resolve a ColorSpec to an actual hex RGB color using the document theme.
|
|
1254
|
-
*
|
|
1255
|
-
* Applies theme color lookup + tint/shade transformations per OOXML spec.
|
|
1256
|
-
*
|
|
1257
|
-
* @param color - The color value (HexColor string or ColorSpec).
|
|
1258
|
-
* @param theme - The document theme (from `doc.theme`).
|
|
1259
|
-
* @returns Resolved hex color string (6 chars, no #), or undefined if unresolvable.
|
|
1260
|
-
*/
|
|
1261
|
-
function resolveThemeColor(color, theme) {
|
|
1262
|
-
if (color === undefined) {
|
|
1263
|
-
return undefined;
|
|
1264
|
-
}
|
|
1265
|
-
if (typeof color === "string") {
|
|
1266
|
-
return color;
|
|
1267
|
-
}
|
|
1268
|
-
// ColorSpec with val — use directly
|
|
1269
|
-
if (color.val && color.val !== "auto") {
|
|
1270
|
-
return color.val;
|
|
1271
|
-
}
|
|
1272
|
-
// Resolve via theme
|
|
1273
|
-
if (!color.themeColor || !theme) {
|
|
1274
|
-
return color.val;
|
|
1275
|
-
}
|
|
1276
|
-
const key = THEME_COLOR_MAP[color.themeColor] ?? color.themeColor;
|
|
1277
|
-
const base = theme.colorScheme.colors[key];
|
|
1278
|
-
if (!base) {
|
|
1279
|
-
return color.val;
|
|
1280
|
-
}
|
|
1281
|
-
// Apply tint or shade
|
|
1282
|
-
if (color.themeTint) {
|
|
1283
|
-
return applyTint(base, parseInt(color.themeTint, 16) / 255);
|
|
1284
|
-
}
|
|
1285
|
-
if (color.themeShade) {
|
|
1286
|
-
return applyShade(base, parseInt(color.themeShade, 16) / 255);
|
|
1287
|
-
}
|
|
1288
|
-
return base;
|
|
1289
|
-
}
|
|
1290
|
-
/** Apply tint to a hex color. tint=1 → white, tint=0 → original. */
|
|
1291
|
-
function applyTint(hex, tint) {
|
|
1292
|
-
const r = parseInt(hex.slice(0, 2), 16);
|
|
1293
|
-
const g = parseInt(hex.slice(2, 4), 16);
|
|
1294
|
-
const b = parseInt(hex.slice(4, 6), 16);
|
|
1295
|
-
const nr = Math.round(r + (255 - r) * tint);
|
|
1296
|
-
const ng = Math.round(g + (255 - g) * tint);
|
|
1297
|
-
const nb = Math.round(b + (255 - b) * tint);
|
|
1298
|
-
return toHex2(nr) + toHex2(ng) + toHex2(nb);
|
|
1299
|
-
}
|
|
1300
|
-
/** Apply shade to a hex color. shade=1 → original, shade=0 → black. */
|
|
1301
|
-
function applyShade(hex, shade) {
|
|
1302
|
-
const r = parseInt(hex.slice(0, 2), 16);
|
|
1303
|
-
const g = parseInt(hex.slice(2, 4), 16);
|
|
1304
|
-
const b = parseInt(hex.slice(4, 6), 16);
|
|
1305
|
-
const nr = Math.round(r * shade);
|
|
1306
|
-
const ng = Math.round(g * shade);
|
|
1307
|
-
const nb = Math.round(b * shade);
|
|
1308
|
-
return toHex2(nr) + toHex2(ng) + toHex2(nb);
|
|
1309
|
-
}
|
|
1310
|
-
function toHex2(n) {
|
|
1311
|
-
const h = Math.max(0, Math.min(255, n)).toString(16);
|
|
1312
|
-
return h.length < 2 ? "0" + h : h;
|
|
1313
|
-
}
|
|
1208
|
+
var color_utils_1 = require("./color-utils");
|
|
1209
|
+
Object.defineProperty(exports, "resolveThemeColor", { enumerable: true, get: function () { return color_utils_1.resolveThemeColor; } });
|
|
1314
1210
|
/** Extract concatenated plain text from a paragraph's runs. */
|
|
1315
1211
|
function paragraphText(para) {
|
|
1316
1212
|
let text = "";
|
|
@@ -1747,163 +1643,3 @@ function countOccurrences(str, search) {
|
|
|
1747
1643
|
}
|
|
1748
1644
|
return str.split(search).length - 1;
|
|
1749
1645
|
}
|
|
1750
|
-
/**
|
|
1751
|
-
* Read an existing DOCX file, replace placeholders with content, and produce a new DOCX.
|
|
1752
|
-
*
|
|
1753
|
-
* Placeholders are strings like `{{name}}` embedded in the document text.
|
|
1754
|
-
* They may span across multiple runs — the patcher handles cross-run matching.
|
|
1755
|
-
*
|
|
1756
|
-
* Supported patch content types:
|
|
1757
|
-
* - `text` — simple text replacement (preserves formatting of the first run)
|
|
1758
|
-
* - `paragraph` — replaces the entire paragraph containing the placeholder
|
|
1759
|
-
* - `table` — replaces the entire paragraph with a table
|
|
1760
|
-
* - `image` — replaces the placeholder with an inline image
|
|
1761
|
-
*
|
|
1762
|
-
* @param buffer - The source DOCX file as a Uint8Array.
|
|
1763
|
-
* @param patches - Array of patch operations to apply.
|
|
1764
|
-
* @param options - Optional compression settings.
|
|
1765
|
-
* @returns New DOCX file as a Uint8Array.
|
|
1766
|
-
*/
|
|
1767
|
-
async function patchDocument(buffer, patches, options) {
|
|
1768
|
-
const doc = await (0, docx_reader_1.readDocx)(buffer);
|
|
1769
|
-
// Build lookup map for quick placeholder matching
|
|
1770
|
-
const patchMap = new Map();
|
|
1771
|
-
for (const patch of patches) {
|
|
1772
|
-
patchMap.set(patch.placeholder, patch);
|
|
1773
|
-
}
|
|
1774
|
-
// Process body content
|
|
1775
|
-
const newBody = [];
|
|
1776
|
-
for (const block of doc.body) {
|
|
1777
|
-
if (block.type === "paragraph") {
|
|
1778
|
-
const result = patchParagraph(block, patchMap);
|
|
1779
|
-
if (result) {
|
|
1780
|
-
if (Array.isArray(result)) {
|
|
1781
|
-
newBody.push(...result);
|
|
1782
|
-
}
|
|
1783
|
-
else {
|
|
1784
|
-
newBody.push(result);
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
else if (block.type === "table") {
|
|
1789
|
-
patchTable(block, patchMap);
|
|
1790
|
-
newBody.push(block);
|
|
1791
|
-
}
|
|
1792
|
-
else {
|
|
1793
|
-
newBody.push(block);
|
|
1794
|
-
}
|
|
1795
|
-
}
|
|
1796
|
-
// Patch headers
|
|
1797
|
-
if (doc.headers) {
|
|
1798
|
-
for (const [, headerDef] of doc.headers) {
|
|
1799
|
-
patchHeaderFooterContent(headerDef.content, patchMap);
|
|
1800
|
-
}
|
|
1801
|
-
}
|
|
1802
|
-
// Patch footers
|
|
1803
|
-
if (doc.footers) {
|
|
1804
|
-
for (const [, footerDef] of doc.footers) {
|
|
1805
|
-
patchHeaderFooterContent(footerDef.content, patchMap);
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
// Add any new images from patches
|
|
1809
|
-
const images = doc.images ? [...doc.images] : [];
|
|
1810
|
-
for (const patch of patches) {
|
|
1811
|
-
if (patch.content.type === "image") {
|
|
1812
|
-
const imgContent = patch.content;
|
|
1813
|
-
const existing = images.find(i => i.fileName === imgContent.image.fileName);
|
|
1814
|
-
if (!existing) {
|
|
1815
|
-
images.push(imgContent.image);
|
|
1816
|
-
}
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
const patched = {
|
|
1820
|
-
...doc,
|
|
1821
|
-
body: newBody,
|
|
1822
|
-
images: images.length > 0 ? images : undefined
|
|
1823
|
-
};
|
|
1824
|
-
return (0, docx_packager_1.packageDocx)(patched, options?.compressionLevel);
|
|
1825
|
-
}
|
|
1826
|
-
/** Patch a paragraph — returns replacement content or null to remove. */
|
|
1827
|
-
function patchParagraph(para, patchMap) {
|
|
1828
|
-
const text = paragraphText(para);
|
|
1829
|
-
for (const [placeholder, patch] of patchMap) {
|
|
1830
|
-
if (!text.includes(placeholder)) {
|
|
1831
|
-
continue;
|
|
1832
|
-
}
|
|
1833
|
-
switch (patch.content.type) {
|
|
1834
|
-
case "text": {
|
|
1835
|
-
replaceInParagraph(para, placeholder, patch.content.text);
|
|
1836
|
-
return para;
|
|
1837
|
-
}
|
|
1838
|
-
case "paragraph": {
|
|
1839
|
-
return patch.content.children;
|
|
1840
|
-
}
|
|
1841
|
-
case "table": {
|
|
1842
|
-
return patch.content.table;
|
|
1843
|
-
}
|
|
1844
|
-
case "image": {
|
|
1845
|
-
const img = patch.content.image;
|
|
1846
|
-
const rId = img.rId ?? `rId_img_${img.fileName}`;
|
|
1847
|
-
const imgContent = {
|
|
1848
|
-
type: "image",
|
|
1849
|
-
rId,
|
|
1850
|
-
width: patch.content.width,
|
|
1851
|
-
height: patch.content.height,
|
|
1852
|
-
altText: img.fileName,
|
|
1853
|
-
name: img.fileName
|
|
1854
|
-
};
|
|
1855
|
-
const newPara = {
|
|
1856
|
-
type: "paragraph",
|
|
1857
|
-
properties: para.properties,
|
|
1858
|
-
children: [{ content: [imgContent] }]
|
|
1859
|
-
};
|
|
1860
|
-
return newPara;
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
}
|
|
1864
|
-
return para;
|
|
1865
|
-
}
|
|
1866
|
-
/** Patch text inside table cells recursively. */
|
|
1867
|
-
function patchTable(table, patchMap) {
|
|
1868
|
-
for (const row of table.rows) {
|
|
1869
|
-
for (const cell of row.cells) {
|
|
1870
|
-
const newContent = [];
|
|
1871
|
-
for (const block of cell.content) {
|
|
1872
|
-
if (block.type === "paragraph") {
|
|
1873
|
-
const result = patchParagraph(block, patchMap);
|
|
1874
|
-
if (result) {
|
|
1875
|
-
if (Array.isArray(result)) {
|
|
1876
|
-
newContent.push(...result);
|
|
1877
|
-
}
|
|
1878
|
-
else {
|
|
1879
|
-
newContent.push(result);
|
|
1880
|
-
}
|
|
1881
|
-
}
|
|
1882
|
-
}
|
|
1883
|
-
else if (block.type === "table") {
|
|
1884
|
-
patchTable(block, patchMap);
|
|
1885
|
-
newContent.push(block);
|
|
1886
|
-
}
|
|
1887
|
-
else {
|
|
1888
|
-
newContent.push(block);
|
|
1889
|
-
}
|
|
1890
|
-
}
|
|
1891
|
-
cell.content = newContent;
|
|
1892
|
-
}
|
|
1893
|
-
}
|
|
1894
|
-
}
|
|
1895
|
-
/** Patch text in header/footer content. */
|
|
1896
|
-
function patchHeaderFooterContent(content, patchMap) {
|
|
1897
|
-
for (const child of content.children) {
|
|
1898
|
-
if (child.type === "paragraph") {
|
|
1899
|
-
for (const [placeholder, patch] of patchMap) {
|
|
1900
|
-
if (patch.content.type === "text") {
|
|
1901
|
-
const text = paragraphText(child);
|
|
1902
|
-
if (text.includes(placeholder)) {
|
|
1903
|
-
replaceInParagraph(child, placeholder, patch.content.text);
|
|
1904
|
-
}
|
|
1905
|
-
}
|
|
1906
|
-
}
|
|
1907
|
-
}
|
|
1908
|
-
}
|
|
1909
|
-
}
|