docxmlater 0.5.0 → 0.7.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 +477 -554
- package/dist/core/Document.d.ts +60 -0
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +537 -3
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentParser.d.ts.map +1 -1
- package/dist/core/DocumentParser.js +5 -1
- package/dist/core/DocumentParser.js.map +1 -1
- package/dist/core/DocumentValidator.js +3 -0
- package/dist/core/DocumentValidator.js.map +1 -1
- package/dist/core/Relationship.d.ts +5 -0
- package/dist/core/Relationship.d.ts.map +1 -1
- package/dist/core/Relationship.js +26 -0
- package/dist/core/Relationship.js.map +1 -1
- package/dist/core/RelationshipManager.d.ts +6 -0
- package/dist/core/RelationshipManager.d.ts.map +1 -1
- package/dist/core/RelationshipManager.js +47 -0
- package/dist/core/RelationshipManager.js.map +1 -1
- package/dist/elements/Bookmark.js +2 -0
- package/dist/elements/Bookmark.js.map +1 -1
- package/dist/elements/BookmarkManager.js +2 -4
- package/dist/elements/BookmarkManager.js.map +1 -1
- package/dist/elements/Comment.js +6 -0
- package/dist/elements/Comment.js.map +1 -1
- package/dist/elements/CommentManager.js +2 -4
- package/dist/elements/CommentManager.js.map +1 -1
- package/dist/elements/Endnote.d.ts +34 -0
- package/dist/elements/Endnote.d.ts.map +1 -0
- package/dist/elements/Endnote.js +99 -0
- package/dist/elements/Endnote.js.map +1 -0
- package/dist/elements/EndnoteManager.d.ts +26 -0
- package/dist/elements/EndnoteManager.d.ts.map +1 -0
- package/dist/elements/EndnoteManager.js +108 -0
- package/dist/elements/EndnoteManager.js.map +1 -0
- package/dist/elements/Field.js +3 -0
- package/dist/elements/Field.js.map +1 -1
- package/dist/elements/Footer.js +3 -1
- package/dist/elements/Footer.js.map +1 -1
- package/dist/elements/Footnote.d.ts +34 -0
- package/dist/elements/Footnote.d.ts.map +1 -0
- package/dist/elements/Footnote.js +99 -0
- package/dist/elements/Footnote.js.map +1 -0
- package/dist/elements/FootnoteManager.d.ts +26 -0
- package/dist/elements/FootnoteManager.d.ts.map +1 -0
- package/dist/elements/FootnoteManager.js +108 -0
- package/dist/elements/FootnoteManager.js.map +1 -0
- package/dist/elements/Header.js +3 -1
- package/dist/elements/Header.js.map +1 -1
- package/dist/elements/HeaderFooterManager.js +4 -0
- package/dist/elements/HeaderFooterManager.js.map +1 -1
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +19 -1
- package/dist/elements/Hyperlink.js.map +1 -1
- package/dist/elements/Image.d.ts +4 -0
- package/dist/elements/Image.d.ts.map +1 -1
- package/dist/elements/Image.js +30 -1
- package/dist/elements/Image.js.map +1 -1
- package/dist/elements/ImageManager.js +6 -0
- package/dist/elements/ImageManager.js.map +1 -1
- package/dist/elements/Paragraph.d.ts +41 -0
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +69 -5
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/Revision.js +5 -0
- package/dist/elements/Revision.js.map +1 -1
- package/dist/elements/RevisionManager.js +2 -4
- package/dist/elements/RevisionManager.js.map +1 -1
- package/dist/elements/Run.d.ts +2 -0
- package/dist/elements/Run.d.ts.map +1 -1
- package/dist/elements/Run.js +29 -4
- package/dist/elements/Run.js.map +1 -1
- package/dist/elements/Section.js +1 -0
- package/dist/elements/Section.js.map +1 -1
- package/dist/elements/Table.d.ts +6 -0
- package/dist/elements/Table.d.ts.map +1 -1
- package/dist/elements/Table.js +69 -2
- package/dist/elements/Table.js.map +1 -1
- package/dist/elements/TableCell.d.ts +9 -0
- package/dist/elements/TableCell.d.ts.map +1 -1
- package/dist/elements/TableCell.js +29 -1
- package/dist/elements/TableCell.js.map +1 -1
- package/dist/elements/TableOfContents.d.ts.map +1 -1
- package/dist/elements/TableOfContents.js +11 -0
- package/dist/elements/TableOfContents.js.map +1 -1
- package/dist/elements/TableOfContentsElement.js +1 -0
- package/dist/elements/TableOfContentsElement.js.map +1 -1
- package/dist/elements/TableRow.js +2 -1
- package/dist/elements/TableRow.js.map +1 -1
- package/dist/formatting/AbstractNumbering.d.ts +5 -0
- package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
- package/dist/formatting/AbstractNumbering.js +42 -0
- package/dist/formatting/AbstractNumbering.js.map +1 -1
- package/dist/formatting/NumberingInstance.d.ts +4 -1
- package/dist/formatting/NumberingInstance.d.ts.map +1 -1
- package/dist/formatting/NumberingInstance.js +20 -3
- package/dist/formatting/NumberingInstance.js.map +1 -1
- package/dist/formatting/NumberingLevel.js +1 -0
- package/dist/formatting/NumberingLevel.js.map +1 -1
- package/dist/formatting/NumberingManager.d.ts +6 -0
- package/dist/formatting/NumberingManager.d.ts.map +1 -1
- package/dist/formatting/NumberingManager.js +37 -0
- package/dist/formatting/NumberingManager.js.map +1 -1
- package/dist/formatting/Style.d.ts +1 -0
- package/dist/formatting/Style.d.ts.map +1 -1
- package/dist/formatting/Style.js +66 -0
- package/dist/formatting/Style.js.map +1 -1
- package/dist/formatting/StylesManager.d.ts +8 -0
- package/dist/formatting/StylesManager.d.ts.map +1 -1
- package/dist/formatting/StylesManager.js +107 -17
- package/dist/formatting/StylesManager.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -1
- package/dist/index.js.map +1 -1
- package/dist/types/formatting.d.ts +47 -0
- package/dist/types/formatting.d.ts.map +1 -0
- package/dist/types/formatting.js +3 -0
- package/dist/types/formatting.js.map +1 -0
- package/dist/utils/validation.d.ts +14 -0
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +74 -0
- package/dist/utils/validation.js.map +1 -1
- package/dist/xml/XMLBuilder.js +1 -3
- package/dist/xml/XMLBuilder.js.map +1 -1
- package/dist/zip/ZipHandler.js +3 -1
- package/dist/zip/ZipHandler.js.map +1 -1
- package/dist/zip/ZipReader.js +3 -5
- package/dist/zip/ZipReader.js.map +1 -1
- package/dist/zip/ZipWriter.js +2 -1
- package/dist/zip/ZipWriter.js.map +1 -1
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -1,694 +1,617 @@
|
|
|
1
|
-
#
|
|
1
|
+
# docXMLater - Professional DOCX Framework
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/docxmlater)
|
|
4
|
+
[](https://github.com/ItMeDiaTech/docXMLater)
|
|
4
5
|
[](https://www.typescriptlang.org/)
|
|
5
|
-
[](https://opensource.org/licenses/MIT)
|
|
6
7
|
|
|
7
|
-
A comprehensive, production-ready TypeScript/JavaScript library for creating, reading, and manipulating Microsoft Word (.docx) documents programmatically.
|
|
8
|
+
A comprehensive, production-ready TypeScript/JavaScript library for creating, reading, and manipulating Microsoft Word (.docx) documents programmatically. Full OpenXML compliance with extensive API coverage.
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
- **High-Level Document API** - Create documents with a simple, intuitive interface
|
|
12
|
-
- **Text Formatting** - Bold, italic, fonts, colors, and 15+ formatting options
|
|
13
|
-
- **Paragraph Formatting** - Alignment, indentation, spacing, keep-with-next
|
|
14
|
-
- **Tables** - Full table support with borders, shading, cell merging
|
|
15
|
-
- **Images** - Embed PNG, JPEG, GIF images with sizing and positioning
|
|
16
|
-
- **Hyperlinks** - Internal and external links with full formatting support
|
|
17
|
-
- **Styles System** - 13 built-in styles + custom style creation
|
|
18
|
-
- **ZIP Archive Handling** - Low-level DOCX manipulation
|
|
19
|
-
- **TypeScript First** - Full type safety with comprehensive definitions
|
|
20
|
-
- **Well Tested** - 205 tests, all passing
|
|
21
|
-
- **Production Ready** - Used in real-world applications
|
|
22
|
-
|
|
23
|
-
## Installation
|
|
10
|
+
## Quick Start
|
|
24
11
|
|
|
25
12
|
```bash
|
|
26
13
|
npm install docxmlater
|
|
27
14
|
```
|
|
28
15
|
|
|
29
|
-
## Quick Start
|
|
30
|
-
|
|
31
|
-
### Create Your First Document
|
|
32
|
-
|
|
33
16
|
```typescript
|
|
34
17
|
import { Document } from "docxmlater";
|
|
35
18
|
|
|
19
|
+
// Create document
|
|
36
20
|
const doc = Document.create();
|
|
21
|
+
doc.createParagraph("Hello World").setStyle("Title");
|
|
37
22
|
|
|
38
|
-
//
|
|
39
|
-
doc.
|
|
40
|
-
doc.createParagraph("Introduction").setStyle("Heading1");
|
|
41
|
-
doc.createParagraph("This is body text with the Normal style.");
|
|
42
|
-
|
|
43
|
-
// Save
|
|
44
|
-
await doc.save("my-document.docx");
|
|
23
|
+
// Save document
|
|
24
|
+
await doc.save("output.docx");
|
|
45
25
|
```
|
|
46
26
|
|
|
47
|
-
|
|
27
|
+
## Complete API Reference
|
|
28
|
+
|
|
29
|
+
### Document Operations
|
|
30
|
+
|
|
31
|
+
| Method | Description | Example |
|
|
32
|
+
| --------------------------------- | ----------------------- | ------------------------------------------------ |
|
|
33
|
+
| `Document.create(options?)` | Create new document | `const doc = Document.create()` |
|
|
34
|
+
| `Document.createEmpty()` | Create minimal document | `const doc = Document.createEmpty()` |
|
|
35
|
+
| `Document.load(path)` | Load from file | `const doc = await Document.load('file.docx')` |
|
|
36
|
+
| `Document.loadFromBuffer(buffer)` | Load from buffer | `const doc = await Document.loadFromBuffer(buf)` |
|
|
37
|
+
| `save(path)` | Save to file | `await doc.save('output.docx')` |
|
|
38
|
+
| `toBuffer()` | Export as buffer | `const buffer = await doc.toBuffer()` |
|
|
39
|
+
| `dispose()` | Clean up resources | `doc.dispose()` |
|
|
40
|
+
|
|
41
|
+
### Content Creation
|
|
42
|
+
|
|
43
|
+
| Method | Description | Example |
|
|
44
|
+
| -------------------------------- | ---------------------- | -------------------------------- |
|
|
45
|
+
| `createParagraph(text?)` | Add paragraph | `doc.createParagraph('Text')` |
|
|
46
|
+
| `createTable(rows, cols)` | Add table | `doc.createTable(3, 4)` |
|
|
47
|
+
| `addParagraph(para)` | Add existing paragraph | `doc.addParagraph(myPara)` |
|
|
48
|
+
| `addTable(table)` | Add existing table | `doc.addTable(myTable)` |
|
|
49
|
+
| `addImage(image)` | Add image | `doc.addImage(myImage)` |
|
|
50
|
+
| `addTableOfContents(toc?)` | Add TOC | `doc.addTableOfContents()` |
|
|
51
|
+
| `insertParagraphAt(index, para)` | Insert at position | `doc.insertParagraphAt(0, para)` |
|
|
52
|
+
|
|
53
|
+
### Content Retrieval
|
|
54
|
+
|
|
55
|
+
| Method | Description | Returns |
|
|
56
|
+
| --------------------- | --------------------- | ------------------------------------------ |
|
|
57
|
+
| `getParagraphs()` | Get all paragraphs | `Paragraph[]` |
|
|
58
|
+
| `getTables()` | Get all tables | `Table[]` |
|
|
59
|
+
| `getBodyElements()` | Get all body elements | `BodyElement[]` |
|
|
60
|
+
| `getParagraphCount()` | Count paragraphs | `number` |
|
|
61
|
+
| `getTableCount()` | Count tables | `number` |
|
|
62
|
+
| `getHyperlinks()` | Get all links | `Array<{hyperlink, paragraph}>` |
|
|
63
|
+
| `getBookmarks()` | Get all bookmarks | `Array<{bookmark, paragraph}>` |
|
|
64
|
+
| `getImages()` | Get all images | `Array<{image, relationshipId, filename}>` |
|
|
65
|
+
|
|
66
|
+
### Content Removal
|
|
67
|
+
|
|
68
|
+
| Method | Description | Returns |
|
|
69
|
+
| ------------------------------ | ------------------ | --------- |
|
|
70
|
+
| `removeParagraph(paraOrIndex)` | Remove paragraph | `boolean` |
|
|
71
|
+
| `removeTable(tableOrIndex)` | Remove table | `boolean` |
|
|
72
|
+
| `clearParagraphs()` | Remove all content | `this` |
|
|
73
|
+
|
|
74
|
+
### Search & Replace
|
|
75
|
+
|
|
76
|
+
| Method | Description | Options |
|
|
77
|
+
| -------------------------------------- | --------------------- | ------------------------------ |
|
|
78
|
+
| `findText(text, options?)` | Find text occurrences | `{caseSensitive?, wholeWord?}` |
|
|
79
|
+
| `replaceText(find, replace, options?)` | Replace all text | `{caseSensitive?, wholeWord?}` |
|
|
80
|
+
| `updateHyperlinkUrls(urlMap)` | Update hyperlink URLs | `Map<oldUrl, newUrl>` |
|
|
81
|
+
|
|
82
|
+
### Document Statistics
|
|
83
|
+
|
|
84
|
+
| Method | Description | Returns |
|
|
85
|
+
| ----------------------------------- | ------------------- | ------------------------------ |
|
|
86
|
+
| `getWordCount()` | Total word count | `number` |
|
|
87
|
+
| `getCharacterCount(includeSpaces?)` | Character count | `number` |
|
|
88
|
+
| `estimateSize()` | Size estimation | `{totalEstimatedMB, warning?}` |
|
|
89
|
+
| `getSizeStats()` | Detailed size stats | `{elements, size, warnings}` |
|
|
90
|
+
|
|
91
|
+
### Text Formatting
|
|
92
|
+
|
|
93
|
+
| Property | Values | Example |
|
|
94
|
+
| ------------- | -------------------------------- | ----------------------- |
|
|
95
|
+
| `bold` | `true/false` | `{bold: true}` |
|
|
96
|
+
| `italic` | `true/false` | `{italic: true}` |
|
|
97
|
+
| `underline` | `'single'/'double'/'dotted'/etc` | `{underline: 'single'}` |
|
|
98
|
+
| `strike` | `true/false` | `{strike: true}` |
|
|
99
|
+
| `font` | Font name | `{font: 'Arial'}` |
|
|
100
|
+
| `size` | Points | `{size: 12}` |
|
|
101
|
+
| `color` | Hex color | `{color: 'FF0000'}` |
|
|
102
|
+
| `highlight` | Color name | `{highlight: 'yellow'}` |
|
|
103
|
+
| `subscript` | `true/false` | `{subscript: true}` |
|
|
104
|
+
| `superscript` | `true/false` | `{superscript: true}` |
|
|
105
|
+
| `smallCaps` | `true/false` | `{smallCaps: true}` |
|
|
106
|
+
| `allCaps` | `true/false` | `{allCaps: true}` |
|
|
107
|
+
|
|
108
|
+
### Paragraph Formatting
|
|
109
|
+
|
|
110
|
+
| Method | Description | Values |
|
|
111
|
+
| ------------------------------ | ------------------- | ----------------------------------- |
|
|
112
|
+
| `setAlignment(align)` | Text alignment | `'left'/'center'/'right'/'justify'` |
|
|
113
|
+
| `setLeftIndent(twips)` | Left indentation | Twips value |
|
|
114
|
+
| `setRightIndent(twips)` | Right indentation | Twips value |
|
|
115
|
+
| `setFirstLineIndent(twips)` | First line indent | Twips value |
|
|
116
|
+
| `setSpaceBefore(twips)` | Space before | Twips value |
|
|
117
|
+
| `setSpaceAfter(twips)` | Space after | Twips value |
|
|
118
|
+
| `setLineSpacing(twips, rule?)` | Line spacing | Twips + rule |
|
|
119
|
+
| `setStyle(styleId)` | Apply style | Style ID |
|
|
120
|
+
| `setKeepNext()` | Keep with next | - |
|
|
121
|
+
| `setKeepLines()` | Keep lines together | - |
|
|
122
|
+
| `setPageBreakBefore()` | Page break before | - |
|
|
123
|
+
|
|
124
|
+
### Table Operations
|
|
125
|
+
|
|
126
|
+
| Method | Description | Example |
|
|
127
|
+
| ----------------------- | -------------------- | ---------------------------------------- |
|
|
128
|
+
| `getRow(index)` | Get table row | `table.getRow(0)` |
|
|
129
|
+
| `getCell(row, col)` | Get table cell | `table.getCell(0, 1)` |
|
|
130
|
+
| `addRow()` | Add new row | `table.addRow()` |
|
|
131
|
+
| `removeRow(index)` | Remove row | `table.removeRow(2)` |
|
|
132
|
+
| `insertColumn(index)` | Insert column | `table.insertColumn(1)` |
|
|
133
|
+
| `removeColumn(index)` | Remove column | `table.removeColumn(3)` |
|
|
134
|
+
| `setWidth(twips)` | Set table width | `table.setWidth(8640)` |
|
|
135
|
+
| `setAlignment(align)` | Table alignment | `table.setAlignment('center')` |
|
|
136
|
+
| `setAllBorders(border)` | Set all borders | `table.setAllBorders({style: 'single'})` |
|
|
137
|
+
| `setBorders(borders)` | Set specific borders | `table.setBorders({top: {...}})` |
|
|
138
|
+
|
|
139
|
+
### Table Cell Operations
|
|
140
|
+
|
|
141
|
+
| Method | Description | Example |
|
|
142
|
+
| ----------------------------- | --------------------- | ------------------------------------- |
|
|
143
|
+
| `createParagraph(text?)` | Add paragraph to cell | `cell.createParagraph('Text')` |
|
|
144
|
+
| `setShading(shading)` | Cell background | `cell.setShading({fill: 'E0E0E0'})` |
|
|
145
|
+
| `setVerticalAlignment(align)` | Vertical align | `cell.setVerticalAlignment('center')` |
|
|
146
|
+
| `setColumnSpan(cols)` | Merge columns | `cell.setColumnSpan(3)` |
|
|
147
|
+
| `setRowSpan(rows)` | Merge rows | `cell.setRowSpan(2)` |
|
|
148
|
+
| `setBorders(borders)` | Cell borders | `cell.setBorders({top: {...}})` |
|
|
149
|
+
| `setWidth(width, type?)` | Cell width | `cell.setWidth(2000, 'dxa')` |
|
|
150
|
+
|
|
151
|
+
### Style Management
|
|
152
|
+
|
|
153
|
+
| Method | Description | Example |
|
|
154
|
+
| ----------------------------- | ------------------ | ---------------------------------- |
|
|
155
|
+
| `addStyle(style)` | Add custom style | `doc.addStyle(myStyle)` |
|
|
156
|
+
| `getStyle(styleId)` | Get style by ID | `doc.getStyle('Heading1')` |
|
|
157
|
+
| `hasStyle(styleId)` | Check style exists | `doc.hasStyle('CustomStyle')` |
|
|
158
|
+
| `getStyles()` | Get all styles | `doc.getStyles()` |
|
|
159
|
+
| `removeStyle(styleId)` | Remove style | `doc.removeStyle('OldStyle')` |
|
|
160
|
+
| `updateStyle(styleId, props)` | Update style | `doc.updateStyle('Normal', {...})` |
|
|
161
|
+
|
|
162
|
+
#### Built-in Styles
|
|
163
|
+
|
|
164
|
+
- `Normal` - Default paragraph
|
|
165
|
+
- `Title` - Document title
|
|
166
|
+
- `Subtitle` - Document subtitle
|
|
167
|
+
- `Heading1` through `Heading9` - Section headings
|
|
168
|
+
- `ListParagraph` - List items
|
|
169
|
+
|
|
170
|
+
### List Management
|
|
171
|
+
|
|
172
|
+
| Method | Description | Returns |
|
|
173
|
+
| --------------------------------------- | ----------------------- | ------- |
|
|
174
|
+
| `createBulletList(levels?, bullets?)` | Create bullet list | `numId` |
|
|
175
|
+
| `createNumberedList(levels?, formats?)` | Create numbered list | `numId` |
|
|
176
|
+
| `createMultiLevelList()` | Create multi-level list | `numId` |
|
|
177
|
+
|
|
178
|
+
### Image Handling
|
|
179
|
+
|
|
180
|
+
| Method | Description | Example |
|
|
181
|
+
| --------------------------------------- | ------------------ | -------------------------------- |
|
|
182
|
+
| `Image.fromFile(path, width?, height?)` | Load from file | `Image.fromFile('pic.jpg')` |
|
|
183
|
+
| `Image.fromBuffer(buffer, ext, w?, h?)` | Load from buffer | `Image.fromBuffer(buf, 'png')` |
|
|
184
|
+
| `setWidth(emus, maintainRatio?)` | Set width | `img.setWidth(inchesToEmus(3))` |
|
|
185
|
+
| `setHeight(emus, maintainRatio?)` | Set height | `img.setHeight(inchesToEmus(2))` |
|
|
186
|
+
| `setSize(width, height)` | Set dimensions | `img.setSize(w, h)` |
|
|
187
|
+
| `setRotation(degrees)` | Rotate image | `img.setRotation(90)` |
|
|
188
|
+
| `setAltText(text)` | Accessibility text | `img.setAltText('Description')` |
|
|
189
|
+
|
|
190
|
+
### Hyperlinks
|
|
191
|
+
|
|
192
|
+
| Method | Description | Example |
|
|
193
|
+
| ------------------------------------------------- | ---------------- | ---------------------------------------------------------- |
|
|
194
|
+
| `Hyperlink.createExternal(url, text, format?)` | Web link | `Hyperlink.createExternal('https://example.com', 'Click')` |
|
|
195
|
+
| `Hyperlink.createEmail(email, text?, format?)` | Email link | `Hyperlink.createEmail('user@example.com')` |
|
|
196
|
+
| `Hyperlink.createInternal(anchor, text, format?)` | Internal link | `Hyperlink.createInternal('Section1', 'Go to')` |
|
|
197
|
+
| `para.addHyperlink(hyperlink)` | Add to paragraph | `para.addHyperlink(link)` |
|
|
198
|
+
|
|
199
|
+
### Headers & Footers
|
|
200
|
+
|
|
201
|
+
| Method | Description | Example |
|
|
202
|
+
| ---------------------------- | ------------------ | -------------------------------- |
|
|
203
|
+
| `setHeader(header)` | Set default header | `doc.setHeader(myHeader)` |
|
|
204
|
+
| `setFooter(footer)` | Set default footer | `doc.setFooter(myFooter)` |
|
|
205
|
+
| `setFirstPageHeader(header)` | First page header | `doc.setFirstPageHeader(header)` |
|
|
206
|
+
| `setFirstPageFooter(footer)` | First page footer | `doc.setFirstPageFooter(footer)` |
|
|
207
|
+
| `setEvenPageHeader(header)` | Even page header | `doc.setEvenPageHeader(header)` |
|
|
208
|
+
| `setEvenPageFooter(footer)` | Even page footer | `doc.setEvenPageFooter(footer)` |
|
|
209
|
+
|
|
210
|
+
### Page Setup
|
|
211
|
+
|
|
212
|
+
| Method | Description | Example |
|
|
213
|
+
| ------------------------------------- | ----------------- | ------------------------------------- |
|
|
214
|
+
| `setPageSize(width, height, orient?)` | Page dimensions | `doc.setPageSize(12240, 15840)` |
|
|
215
|
+
| `setPageOrientation(orientation)` | Page orientation | `doc.setPageOrientation('landscape')` |
|
|
216
|
+
| `setMargins(margins)` | Page margins | `doc.setMargins({top: 1440, ...})` |
|
|
217
|
+
| `setLanguage(language)` | Document language | `doc.setLanguage('en-US')` |
|
|
218
|
+
|
|
219
|
+
### Document Properties
|
|
220
|
+
|
|
221
|
+
| Method | Description | Properties |
|
|
222
|
+
| ---------------------- | ------------ | ------------------------------------- |
|
|
223
|
+
| `setProperties(props)` | Set metadata | `{title, subject, creator, keywords}` |
|
|
224
|
+
| `getProperties()` | Get metadata | Returns all properties |
|
|
225
|
+
|
|
226
|
+
### Advanced Features
|
|
227
|
+
|
|
228
|
+
#### Bookmarks
|
|
229
|
+
|
|
230
|
+
| Method | Description |
|
|
231
|
+
| ---------------------------------------- | ------------------- |
|
|
232
|
+
| `createBookmark(name)` | Create bookmark |
|
|
233
|
+
| `createHeadingBookmark(text)` | Auto-named bookmark |
|
|
234
|
+
| `getBookmark(name)` | Get by name |
|
|
235
|
+
| `hasBookmark(name)` | Check existence |
|
|
236
|
+
| `addBookmarkToParagraph(para, bookmark)` | Add to paragraph |
|
|
237
|
+
|
|
238
|
+
#### Comments
|
|
239
|
+
|
|
240
|
+
| Method | Description |
|
|
241
|
+
| ------------------------------------------- | ----------------- |
|
|
242
|
+
| `createComment(author, content, initials?)` | Add comment |
|
|
243
|
+
| `createReply(parentId, author, content)` | Reply to comment |
|
|
244
|
+
| `getComment(id)` | Get by ID |
|
|
245
|
+
| `getAllComments()` | Get all top-level |
|
|
246
|
+
| `addCommentToParagraph(para, comment)` | Add to paragraph |
|
|
247
|
+
|
|
248
|
+
#### Track Changes
|
|
249
|
+
|
|
250
|
+
| Method | Description |
|
|
251
|
+
| ------------------------------------ | ----------------- |
|
|
252
|
+
| `trackInsertion(para, author, text)` | Track insertion |
|
|
253
|
+
| `trackDeletion(para, author, text)` | Track deletion |
|
|
254
|
+
| `isTrackingChanges()` | Check if tracking |
|
|
255
|
+
| `getRevisionStats()` | Get statistics |
|
|
256
|
+
|
|
257
|
+
#### Footnotes & Endnotes
|
|
258
|
+
|
|
259
|
+
| Method | Description |
|
|
260
|
+
| -------------------------- | ---------------- |
|
|
261
|
+
| `FootnoteManager.create()` | Manage footnotes |
|
|
262
|
+
| `EndnoteManager.create()` | Manage endnotes |
|
|
263
|
+
|
|
264
|
+
### Low-Level Document Parts
|
|
265
|
+
|
|
266
|
+
| Method | Description | Example |
|
|
267
|
+
| ---------------------------- | --------------------- | ------------------------------------------------- |
|
|
268
|
+
| `getPart(partName)` | Get document part | `doc.getPart('word/document.xml')` |
|
|
269
|
+
| `setPart(partName, content)` | Set document part | `doc.setPart('custom.xml', data)` |
|
|
270
|
+
| `removePart(partName)` | Remove part | `doc.removePart('custom.xml')` |
|
|
271
|
+
| `listParts()` | List all parts | `const parts = await doc.listParts()` |
|
|
272
|
+
| `partExists(partName)` | Check part exists | `if (await doc.partExists('...'))` |
|
|
273
|
+
| `getContentTypes()` | Get content types | `const types = await doc.getContentTypes()` |
|
|
274
|
+
| `addContentType(part, type)` | Register content type | `doc.addContentType('.json', 'application/json')` |
|
|
275
|
+
|
|
276
|
+
### Unit Conversion Utilities
|
|
277
|
+
|
|
278
|
+
| Function | Description | Example |
|
|
279
|
+
| ---------------------------- | -------------------- | --------------------------- |
|
|
280
|
+
| `inchesToTwips(inches)` | Inches to twips | `inchesToTwips(1)` // 1440 |
|
|
281
|
+
| `inchesToEmus(inches)` | Inches to EMUs | `inchesToEmus(1)` // 914400 |
|
|
282
|
+
| `cmToTwips(cm)` | Centimeters to twips | `cmToTwips(2.54)` // 1440 |
|
|
283
|
+
| `pointsToTwips(points)` | Points to twips | `pointsToTwips(12)` // 240 |
|
|
284
|
+
| `pixelsToEmus(pixels, dpi?)` | Pixels to EMUs | `pixelsToEmus(96)` |
|
|
285
|
+
|
|
286
|
+
## Common Recipes
|
|
287
|
+
|
|
288
|
+
### Create a Simple Document
|
|
48
289
|
|
|
49
290
|
```typescript
|
|
50
291
|
const doc = Document.create();
|
|
292
|
+
doc.createParagraph("Title").setStyle("Title");
|
|
293
|
+
doc.createParagraph("This is a simple document.");
|
|
294
|
+
await doc.save("simple.docx");
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
### Add Formatted Text
|
|
51
298
|
|
|
52
|
-
|
|
299
|
+
```typescript
|
|
53
300
|
const para = doc.createParagraph();
|
|
54
|
-
para.addText("Bold
|
|
301
|
+
para.addText("Bold", { bold: true });
|
|
55
302
|
para.addText(" and ");
|
|
56
|
-
para.addText("
|
|
57
|
-
|
|
58
|
-
await doc.save("formatted.docx");
|
|
303
|
+
para.addText("Colored", { color: "FF0000" });
|
|
59
304
|
```
|
|
60
305
|
|
|
61
|
-
### Create
|
|
306
|
+
### Create a Table with Borders
|
|
62
307
|
|
|
63
308
|
```typescript
|
|
64
|
-
const doc = Document.create();
|
|
65
|
-
|
|
66
|
-
// Create a 3x3 table
|
|
67
309
|
const table = doc.createTable(3, 3);
|
|
68
|
-
|
|
69
|
-
// Add borders
|
|
70
310
|
table.setAllBorders({ style: "single", size: 8, color: "000000" });
|
|
71
|
-
|
|
72
|
-
// Populate cells
|
|
73
311
|
table.getCell(0, 0)?.createParagraph("Header 1");
|
|
74
|
-
table.getCell(0, 1)?.createParagraph("Header 2");
|
|
75
|
-
|
|
76
|
-
// Add shading to header row
|
|
77
312
|
table.getRow(0)?.getCell(0)?.setShading({ fill: "4472C4" });
|
|
78
|
-
|
|
79
|
-
await doc.save("table.docx");
|
|
80
313
|
```
|
|
81
314
|
|
|
82
|
-
###
|
|
315
|
+
### Insert an Image
|
|
83
316
|
|
|
84
317
|
```typescript
|
|
85
|
-
import {
|
|
86
|
-
|
|
87
|
-
const doc = Document.create();
|
|
88
|
-
|
|
89
|
-
// Add title
|
|
90
|
-
doc.createParagraph("Document with Image").setStyle("Title");
|
|
91
|
-
|
|
92
|
-
// Create image from file
|
|
93
|
-
const image = Image.fromFile("./photo.png");
|
|
94
|
-
image.setWidth(inchesToEmus(4), true); // 4 inches wide, maintain aspect ratio
|
|
318
|
+
import { Image, inchesToEmus } from "docxmlater";
|
|
95
319
|
|
|
96
|
-
|
|
320
|
+
const image = Image.fromFile("./photo.jpg");
|
|
321
|
+
image.setWidth(inchesToEmus(4), true); // 4 inches, maintain ratio
|
|
97
322
|
doc.addImage(image);
|
|
98
|
-
|
|
99
|
-
// Add caption
|
|
100
|
-
doc
|
|
101
|
-
.createParagraph("Figure 1: Sample image")
|
|
102
|
-
.setAlignment("center")
|
|
103
|
-
.addText("Figure 1: Sample image", { italic: true, size: 10 });
|
|
104
|
-
|
|
105
|
-
await doc.save("with-image.docx");
|
|
106
323
|
```
|
|
107
324
|
|
|
108
|
-
### Add
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
import { Document, Hyperlink } from "docxmlater";
|
|
112
|
-
|
|
113
|
-
const doc = Document.create();
|
|
114
|
-
|
|
115
|
-
// External link (to website)
|
|
116
|
-
const para1 = doc.createParagraph();
|
|
117
|
-
para1.addText("Visit ");
|
|
118
|
-
para1.addHyperlink(Hyperlink.createExternal("https://example.com", "our website"));
|
|
119
|
-
para1.addText(" for more information.");
|
|
120
|
-
|
|
121
|
-
// Email link
|
|
122
|
-
const para2 = doc.createParagraph();
|
|
123
|
-
para2.addHyperlink(Hyperlink.createEmail("user@example.com", "Contact us"));
|
|
124
|
-
|
|
125
|
-
// Internal link (to bookmark - requires bookmark to be defined)
|
|
126
|
-
const para3 = doc.createParagraph();
|
|
127
|
-
para3.addHyperlink(Hyperlink.createInternal("Section1", "Jump to Section 1"));
|
|
128
|
-
|
|
129
|
-
await doc.save("with-links.docx");
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
**Important:** External hyperlinks require relationship registration. Always use `Document.save()` or `Document.toBuffer()` which automatically handle this. Manually calling `toXML()` on external hyperlinks without setting relationship IDs will throw an error to prevent document corruption.
|
|
133
|
-
|
|
134
|
-
See [Hyperlink Best Practices](OPENXML_STRUCTURE_GUIDE.md#hyperlink-best-practices) for complete documentation.
|
|
135
|
-
|
|
136
|
-
### Use Custom Styles
|
|
137
|
-
|
|
138
|
-
```typescript
|
|
139
|
-
import { Document, Style } from "docxmlater";
|
|
140
|
-
|
|
141
|
-
const doc = Document.create();
|
|
142
|
-
|
|
143
|
-
// Create a custom style
|
|
144
|
-
const alertStyle = Style.create({
|
|
145
|
-
styleId: "Alert",
|
|
146
|
-
name: "Alert",
|
|
147
|
-
type: "paragraph",
|
|
148
|
-
basedOn: "Normal",
|
|
149
|
-
runFormatting: {
|
|
150
|
-
bold: true,
|
|
151
|
-
color: "FF0000",
|
|
152
|
-
size: 12,
|
|
153
|
-
},
|
|
154
|
-
paragraphFormatting: {
|
|
155
|
-
alignment: "center",
|
|
156
|
-
},
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
doc.addStyle(alertStyle);
|
|
160
|
-
doc.createParagraph("Important Warning").setStyle("Alert");
|
|
161
|
-
|
|
162
|
-
await doc.save("custom-styles.docx");
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## Core Concepts
|
|
166
|
-
|
|
167
|
-
### Document Class
|
|
168
|
-
|
|
169
|
-
The high-level API for creating Word documents:
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
// Create new document
|
|
173
|
-
const doc = Document.create({
|
|
174
|
-
properties: {
|
|
175
|
-
title: "My Document",
|
|
176
|
-
creator: "DocXML",
|
|
177
|
-
subject: "Example",
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// Add content
|
|
182
|
-
doc.createParagraph("Content here");
|
|
183
|
-
doc.createTable(5, 3);
|
|
184
|
-
|
|
185
|
-
// Save
|
|
186
|
-
await doc.save("output.docx");
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
### Paragraphs and Runs
|
|
190
|
-
|
|
191
|
-
Paragraphs contain runs of formatted text:
|
|
325
|
+
### Add a Hyperlink
|
|
192
326
|
|
|
193
327
|
```typescript
|
|
194
328
|
const para = doc.createParagraph();
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
para.addText(" Italic", { italic: true });
|
|
200
|
-
|
|
201
|
-
// Set paragraph formatting
|
|
202
|
-
para.setAlignment("center");
|
|
203
|
-
para.setSpaceAfter(240);
|
|
329
|
+
para.addText("Visit ");
|
|
330
|
+
para.addHyperlink(
|
|
331
|
+
Hyperlink.createExternal("https://example.com", "our website")
|
|
332
|
+
);
|
|
204
333
|
```
|
|
205
334
|
|
|
206
|
-
###
|
|
207
|
-
|
|
208
|
-
Create tables with full formatting control:
|
|
335
|
+
### Search and Replace Text
|
|
209
336
|
|
|
210
337
|
```typescript
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
table.setWidth(8640); // Full page width
|
|
215
|
-
table.setAllBorders({ style: "single", size: 6 });
|
|
216
|
-
|
|
217
|
-
// Access cells
|
|
218
|
-
const cell = table.getCell(0, 0);
|
|
219
|
-
cell?.createParagraph("Cell content");
|
|
220
|
-
cell?.setShading({ fill: "D9E1F2" });
|
|
221
|
-
cell?.setVerticalAlignment("center");
|
|
338
|
+
// Find all occurrences
|
|
339
|
+
const results = doc.findText("old text", { caseSensitive: true });
|
|
340
|
+
console.log(`Found ${results.length} occurrences`);
|
|
222
341
|
|
|
223
|
-
//
|
|
224
|
-
|
|
342
|
+
// Replace all
|
|
343
|
+
const count = doc.replaceText("old text", "new text", { wholeWord: true });
|
|
344
|
+
console.log(`Replaced ${count} occurrences`);
|
|
225
345
|
```
|
|
226
346
|
|
|
227
|
-
###
|
|
228
|
-
|
|
229
|
-
13 built-in styles ready to use:
|
|
347
|
+
### Load and Modify Existing Document
|
|
230
348
|
|
|
231
349
|
```typescript
|
|
232
|
-
|
|
233
|
-
doc.createParagraph("
|
|
234
|
-
doc.createParagraph("Subtitle").setStyle("Subtitle");
|
|
235
|
-
doc.createParagraph("Chapter 1").setStyle("Heading1");
|
|
236
|
-
doc.createParagraph("Section 1.1").setStyle("Heading2");
|
|
237
|
-
doc.createParagraph("Body text").setStyle("Normal");
|
|
238
|
-
|
|
239
|
-
// Check available styles
|
|
240
|
-
console.log(doc.getStylesManager().getStyleCount()); // 13
|
|
241
|
-
|
|
242
|
-
// Create custom styles (see examples)
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
## API Overview
|
|
350
|
+
const doc = await Document.load("existing.docx");
|
|
351
|
+
doc.createParagraph("Added paragraph");
|
|
246
352
|
|
|
247
|
-
|
|
353
|
+
// Update all hyperlinks
|
|
354
|
+
const urlMap = new Map([["https://old-site.com", "https://new-site.com"]]);
|
|
355
|
+
doc.updateHyperlinkUrls(urlMap);
|
|
248
356
|
|
|
249
|
-
|
|
250
|
-
// Creating
|
|
251
|
-
Document.create(options?)
|
|
252
|
-
Document.load(filePath)
|
|
253
|
-
Document.loadFromBuffer(buffer)
|
|
254
|
-
|
|
255
|
-
// Content
|
|
256
|
-
doc.createParagraph(text?)
|
|
257
|
-
doc.createTable(rows, columns)
|
|
258
|
-
doc.addParagraph(paragraph)
|
|
259
|
-
doc.addTable(table)
|
|
260
|
-
|
|
261
|
-
// Styles
|
|
262
|
-
doc.addStyle(style)
|
|
263
|
-
doc.getStyle(styleId)
|
|
264
|
-
doc.hasStyle(styleId)
|
|
265
|
-
doc.getStylesManager()
|
|
266
|
-
|
|
267
|
-
// Saving
|
|
268
|
-
doc.save(filePath)
|
|
269
|
-
doc.toBuffer()
|
|
270
|
-
|
|
271
|
-
// Access
|
|
272
|
-
doc.getParagraphs()
|
|
273
|
-
doc.getTables()
|
|
274
|
-
doc.getImageManager()
|
|
275
|
-
doc.getProperties()
|
|
276
|
-
doc.setProperties(props)
|
|
277
|
-
|
|
278
|
-
// Images
|
|
279
|
-
doc.addImage(image)
|
|
357
|
+
await doc.save("modified.docx");
|
|
280
358
|
```
|
|
281
359
|
|
|
282
|
-
###
|
|
360
|
+
### Create Lists
|
|
283
361
|
|
|
284
362
|
```typescript
|
|
285
|
-
//
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
//
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
para.setSpaceBefore(twips)
|
|
295
|
-
para.setSpaceAfter(twips)
|
|
296
|
-
para.setLineSpacing(twips, rule?)
|
|
297
|
-
|
|
298
|
-
// Styles
|
|
299
|
-
para.setStyle(styleId)
|
|
300
|
-
|
|
301
|
-
// Special
|
|
302
|
-
para.setKeepNext()
|
|
303
|
-
para.setKeepLines()
|
|
304
|
-
para.setPageBreakBefore()
|
|
363
|
+
// Bullet list
|
|
364
|
+
const bulletId = doc.createBulletList(3);
|
|
365
|
+
doc.createParagraph("First item").setNumbering(bulletId, 0);
|
|
366
|
+
doc.createParagraph("Second item").setNumbering(bulletId, 0);
|
|
367
|
+
|
|
368
|
+
// Numbered list
|
|
369
|
+
const numberId = doc.createNumberedList(3);
|
|
370
|
+
doc.createParagraph("Step 1").setNumbering(numberId, 0);
|
|
371
|
+
doc.createParagraph("Step 2").setNumbering(numberId, 0);
|
|
305
372
|
```
|
|
306
373
|
|
|
307
|
-
###
|
|
374
|
+
### Apply Custom Styles
|
|
308
375
|
|
|
309
376
|
```typescript
|
|
310
|
-
|
|
311
|
-
bold: true,
|
|
312
|
-
italic: true,
|
|
313
|
-
underline: "single",
|
|
314
|
-
font: "Arial",
|
|
315
|
-
size: 12, // points
|
|
316
|
-
color: "FF0000", // hex without #
|
|
317
|
-
highlight: "yellow",
|
|
318
|
-
strike: true,
|
|
319
|
-
subscript: true,
|
|
320
|
-
superscript: true,
|
|
321
|
-
smallCaps: true,
|
|
322
|
-
allCaps: true,
|
|
323
|
-
};
|
|
324
|
-
```
|
|
377
|
+
import { Style } from "docxmlater";
|
|
325
378
|
|
|
326
|
-
|
|
379
|
+
const customStyle = Style.create({
|
|
380
|
+
styleId: "CustomHeading",
|
|
381
|
+
name: "Custom Heading",
|
|
382
|
+
basedOn: "Normal",
|
|
383
|
+
runFormatting: { bold: true, size: 14, color: "2E74B5" },
|
|
384
|
+
paragraphFormatting: { alignment: "center", spaceAfter: 240 },
|
|
385
|
+
});
|
|
327
386
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
const table = doc.createTable(rows, cols);
|
|
331
|
-
|
|
332
|
-
// Access
|
|
333
|
-
table.getRow(index);
|
|
334
|
-
table.getCell(rowIndex, colIndex);
|
|
335
|
-
|
|
336
|
-
// Formatting
|
|
337
|
-
table.setWidth(twips);
|
|
338
|
-
table.setAlignment("left" | "center" | "right");
|
|
339
|
-
table.setAllBorders(border);
|
|
340
|
-
table.setBorders(borders);
|
|
341
|
-
table.setLayout("auto" | "fixed");
|
|
387
|
+
doc.addStyle(customStyle);
|
|
388
|
+
doc.createParagraph("Custom Styled Text").setStyle("CustomHeading");
|
|
342
389
|
```
|
|
343
390
|
|
|
344
|
-
###
|
|
391
|
+
### Add Headers and Footers
|
|
345
392
|
|
|
346
393
|
```typescript
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
//
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
394
|
+
import { Header, Footer, Field } from "docxmlater";
|
|
395
|
+
|
|
396
|
+
// Header with page numbers
|
|
397
|
+
const header = Header.create();
|
|
398
|
+
header.addParagraph("Document Title").setAlignment("center");
|
|
399
|
+
|
|
400
|
+
// Footer with page numbers
|
|
401
|
+
const footer = Footer.create();
|
|
402
|
+
const footerPara = footer.addParagraph();
|
|
403
|
+
footerPara.addText("Page ");
|
|
404
|
+
footerPara.addField(Field.create({ type: "PAGE" }));
|
|
405
|
+
footerPara.addText(" of ");
|
|
406
|
+
footerPara.addField(Field.create({ type: "NUMPAGES" }));
|
|
407
|
+
|
|
408
|
+
doc.setHeader(header);
|
|
409
|
+
doc.setFooter(footer);
|
|
357
410
|
```
|
|
358
411
|
|
|
359
|
-
###
|
|
412
|
+
### Work with Document Statistics
|
|
360
413
|
|
|
361
414
|
```typescript
|
|
362
|
-
//
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
//
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
image.getWidth()
|
|
374
|
-
image.getHeight()
|
|
375
|
-
image.getExtension()
|
|
376
|
-
image.getImageData()
|
|
415
|
+
// Get word and character counts
|
|
416
|
+
console.log("Words:", doc.getWordCount());
|
|
417
|
+
console.log("Characters:", doc.getCharacterCount());
|
|
418
|
+
console.log("Characters (no spaces):", doc.getCharacterCount(false));
|
|
419
|
+
|
|
420
|
+
// Check document size
|
|
421
|
+
const size = doc.estimateSize();
|
|
422
|
+
if (size.warning) {
|
|
423
|
+
console.warn(size.warning);
|
|
424
|
+
}
|
|
425
|
+
console.log(`Estimated size: ${size.totalEstimatedMB} MB`);
|
|
377
426
|
```
|
|
378
427
|
|
|
379
|
-
###
|
|
428
|
+
### Handle Large Documents Efficiently
|
|
380
429
|
|
|
381
430
|
```typescript
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
// Generic constructor
|
|
389
|
-
Hyperlink.create(properties)
|
|
390
|
-
new Hyperlink(properties)
|
|
391
|
-
|
|
392
|
-
// Properties
|
|
393
|
-
hyperlink.getText()
|
|
394
|
-
hyperlink.setText(text)
|
|
395
|
-
hyperlink.getUrl()
|
|
396
|
-
hyperlink.getAnchor()
|
|
397
|
-
hyperlink.getTooltip()
|
|
398
|
-
hyperlink.setTooltip(tooltip)
|
|
399
|
-
hyperlink.setFormatting(formatting)
|
|
400
|
-
hyperlink.getFormatting()
|
|
401
|
-
hyperlink.isExternal()
|
|
402
|
-
hyperlink.isInternal()
|
|
403
|
-
|
|
404
|
-
// ⚠️ IMPORTANT: Relationship Management
|
|
405
|
-
// External links require relationship IDs before XML generation
|
|
406
|
-
// Always use Document.save() or Document.toBuffer() which handle this automatically
|
|
407
|
-
// Manual toXML() on external links without relationship IDs will throw error
|
|
408
|
-
hyperlink.setRelationshipId(id) // Usually managed by Document, not called directly
|
|
409
|
-
hyperlink.getRelationshipId()
|
|
410
|
-
hyperlink.toXML() // ⚠️ Requires relationshipId for external links
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
## Built-in Styles
|
|
414
|
-
|
|
415
|
-
All documents include 13 ready-to-use styles:
|
|
416
|
-
|
|
417
|
-
| Style | Description | Font | Size | Color |
|
|
418
|
-
| ----------------- | ------------------- | ------------- | ------- | --------------- |
|
|
419
|
-
| **Normal** | Default paragraph | Calibri | 11pt | Black |
|
|
420
|
-
| **Heading1** | Major headings | Calibri Light | 16pt | Blue (#2E74B5) |
|
|
421
|
-
| **Heading2** | Section headings | Calibri Light | 13pt | Blue (#1F4D78) |
|
|
422
|
-
| **Heading3-9** | Subsection headings | Calibri Light | 12-11pt | Blue (#1F4D78) |
|
|
423
|
-
| **Title** | Document title | Calibri Light | 28pt | Blue (#2E74B5) |
|
|
424
|
-
| **Subtitle** | Document subtitle | Calibri Light | 14pt | Gray, Italic |
|
|
425
|
-
| **ListParagraph** | List items | Calibri | 11pt | Black, Indented |
|
|
426
|
-
|
|
427
|
-
See [Using Styles Guide](docs/guides/using-styles.md) for complete documentation.
|
|
428
|
-
|
|
429
|
-
## Examples
|
|
430
|
-
|
|
431
|
-
The `examples/` directory contains comprehensive examples:
|
|
432
|
-
|
|
433
|
-
### Basic Examples (`examples/01-basic/`)
|
|
434
|
-
|
|
435
|
-
- Creating simple documents
|
|
436
|
-
- Reading and modifying DOCX files
|
|
437
|
-
- Working with ZIP archives
|
|
438
|
-
|
|
439
|
-
### Text Formatting (`examples/02-text/`)
|
|
440
|
-
|
|
441
|
-
- Paragraph formatting examples
|
|
442
|
-
- Text formatting (bold, italic, colors)
|
|
443
|
-
- Advanced formatting techniques
|
|
444
|
-
|
|
445
|
-
### Tables (`examples/03-tables/`)
|
|
446
|
-
|
|
447
|
-
- Simple tables
|
|
448
|
-
- Tables with borders and shading
|
|
449
|
-
- Complex tables with merged cells
|
|
450
|
-
|
|
451
|
-
### Styles (`examples/04-styles/`)
|
|
452
|
-
|
|
453
|
-
- Using built-in styles
|
|
454
|
-
- Creating custom styles
|
|
455
|
-
- Style inheritance
|
|
456
|
-
|
|
457
|
-
### Images (`examples/05-images/`)
|
|
458
|
-
|
|
459
|
-
- Adding images from files and buffers
|
|
460
|
-
- Sizing and resizing images
|
|
461
|
-
- Multiple images in documents
|
|
462
|
-
- Images with text content
|
|
463
|
-
|
|
464
|
-
### Hyperlinks (`examples/07-hyperlinks/`)
|
|
465
|
-
|
|
466
|
-
- External hyperlinks (websites, emails)
|
|
467
|
-
- Internal hyperlinks (bookmarks)
|
|
468
|
-
- Hyperlink formatting and tooltips
|
|
469
|
-
- Validation and best practices
|
|
470
|
-
|
|
471
|
-
### Complete Examples (`examples/06-complete/`)
|
|
472
|
-
|
|
473
|
-
- Professional reports
|
|
474
|
-
- Invoice templates
|
|
475
|
-
- Styled documents
|
|
431
|
+
const doc = Document.create({
|
|
432
|
+
maxMemoryUsagePercent: 80,
|
|
433
|
+
maxRssMB: 2048,
|
|
434
|
+
maxImageCount: 50,
|
|
435
|
+
maxTotalImageSizeMB: 100,
|
|
436
|
+
});
|
|
476
437
|
|
|
477
|
-
|
|
438
|
+
// Process document...
|
|
478
439
|
|
|
479
|
-
|
|
480
|
-
|
|
440
|
+
// Clean up resources after saving
|
|
441
|
+
await doc.save("large-document.docx");
|
|
442
|
+
doc.dispose(); // Free memory
|
|
481
443
|
```
|
|
482
444
|
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
- **[Getting Started Guide](docs/guides/getting-started.md)** - Your first document
|
|
486
|
-
- **[Using Styles](docs/guides/using-styles.md)** - Complete styles guide
|
|
487
|
-
- **[Working with Tables](docs/guides/working-with-tables.md)** - Table guide
|
|
488
|
-
- **[API Reference](docs/api/)** - Complete API documentation
|
|
489
|
-
- **[Architecture](docs/architecture/)** - System architecture
|
|
490
|
-
|
|
491
|
-
## Advanced Usage
|
|
492
|
-
|
|
493
|
-
### Load and Modify Existing Documents
|
|
445
|
+
### Direct XML Access (Advanced)
|
|
494
446
|
|
|
495
447
|
```typescript
|
|
496
|
-
//
|
|
497
|
-
const
|
|
448
|
+
// Get raw XML
|
|
449
|
+
const documentXml = await doc.getPart("word/document.xml");
|
|
450
|
+
console.log(documentXml?.content);
|
|
498
451
|
|
|
499
|
-
//
|
|
500
|
-
doc.
|
|
452
|
+
// Modify raw XML (use with caution)
|
|
453
|
+
await doc.setPart("word/custom.xml", "<custom>data</custom>");
|
|
454
|
+
await doc.addContentType("/word/custom.xml", "application/xml");
|
|
501
455
|
|
|
502
|
-
//
|
|
503
|
-
await doc.
|
|
456
|
+
// List all parts
|
|
457
|
+
const parts = await doc.listParts();
|
|
458
|
+
console.log("Document contains:", parts.length, "parts");
|
|
504
459
|
```
|
|
505
460
|
|
|
506
|
-
|
|
461
|
+
## Features
|
|
507
462
|
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
463
|
+
- **Full OpenXML Compliance** - Follows ECMA-376 standard
|
|
464
|
+
- **TypeScript First** - Complete type definitions
|
|
465
|
+
- **Memory Efficient** - Handles large documents with streaming
|
|
466
|
+
- **Atomic Saves** - Prevents corruption with temp file pattern
|
|
467
|
+
- **Rich Formatting** - Complete text and paragraph formatting
|
|
468
|
+
- **Tables** - Full support with borders, shading, merging
|
|
469
|
+
- **Images** - PNG, JPEG, GIF with sizing and positioning
|
|
470
|
+
- **Hyperlinks** - External, internal, and email links
|
|
471
|
+
- **Styles** - 13 built-in styles + custom style creation
|
|
472
|
+
- **Lists** - Bullets, numbering, multi-level
|
|
473
|
+
- **Headers/Footers** - Different first/even/odd pages
|
|
474
|
+
- **Search & Replace** - With case and whole word options
|
|
475
|
+
- **Document Stats** - Word count, character count, size estimation
|
|
476
|
+
- **Track Changes** - Insertions and deletions with authors
|
|
477
|
+
- **Comments** - With replies and threading
|
|
478
|
+
- **Bookmarks** - For internal navigation
|
|
479
|
+
- **Low-level Access** - Direct ZIP and XML manipulation
|
|
480
|
+
|
|
481
|
+
## Performance
|
|
482
|
+
|
|
483
|
+
- Process 100+ page documents efficiently
|
|
484
|
+
- Atomic save pattern prevents corruption
|
|
485
|
+
- Memory management for large files
|
|
486
|
+
- Lazy loading of document parts
|
|
487
|
+
- Resource cleanup with `dispose()`
|
|
512
488
|
|
|
513
|
-
|
|
514
|
-
const buffer = await doc.toBuffer();
|
|
489
|
+
## Testing
|
|
515
490
|
|
|
516
|
-
|
|
517
|
-
|
|
491
|
+
```bash
|
|
492
|
+
npm test # Run all tests
|
|
493
|
+
npm run test:watch # Watch mode
|
|
494
|
+
npm run test:coverage # Coverage report
|
|
518
495
|
```
|
|
519
496
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
For advanced users, direct ZIP manipulation is available:
|
|
523
|
-
|
|
524
|
-
```typescript
|
|
525
|
-
import { ZipHandler, DOCX_PATHS } from "docxmlater";
|
|
526
|
-
|
|
527
|
-
const handler = new ZipHandler();
|
|
528
|
-
await handler.load("document.docx");
|
|
529
|
-
|
|
530
|
-
// Direct XML access
|
|
531
|
-
const xml = handler.getFileAsString(DOCX_PATHS.DOCUMENT);
|
|
532
|
-
handler.updateFile(DOCX_PATHS.DOCUMENT, modifiedXml);
|
|
533
|
-
|
|
534
|
-
await handler.save("output.docx");
|
|
535
|
-
```
|
|
497
|
+
**Current:** 253 tests passing | 100% core functionality covered
|
|
536
498
|
|
|
537
499
|
## Development
|
|
538
500
|
|
|
539
|
-
### Setup
|
|
540
|
-
|
|
541
501
|
```bash
|
|
542
502
|
# Install dependencies
|
|
543
503
|
npm install
|
|
544
504
|
|
|
545
|
-
# Build
|
|
505
|
+
# Build TypeScript
|
|
546
506
|
npm run build
|
|
547
507
|
|
|
548
|
-
# Run
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
# Run tests with coverage
|
|
552
|
-
npm run test:coverage
|
|
508
|
+
# Run examples
|
|
509
|
+
npx ts-node examples/simple-document.ts
|
|
553
510
|
```
|
|
554
511
|
|
|
555
|
-
|
|
512
|
+
## Project Structure
|
|
556
513
|
|
|
557
|
-
```
|
|
514
|
+
```text
|
|
558
515
|
src/
|
|
559
|
-
├── core/
|
|
560
|
-
├── elements/
|
|
561
|
-
├── formatting/
|
|
562
|
-
├── xml/ #
|
|
563
|
-
├── zip/ #
|
|
564
|
-
└── utils/ # Validation
|
|
565
|
-
|
|
566
|
-
tests/
|
|
567
|
-
├── core/ # Document tests
|
|
568
|
-
├── elements/ # Element tests
|
|
569
|
-
├── formatting/ # Style tests (pending)
|
|
570
|
-
├── zip/ # ZIP tests
|
|
571
|
-
└── utils/ # Utility tests
|
|
572
|
-
|
|
573
|
-
docs/
|
|
574
|
-
├── api/ # API reference
|
|
575
|
-
├── guides/ # User guides
|
|
576
|
-
└── architecture/ # Architecture docs
|
|
516
|
+
├── core/ # Document, Parser, Generator, Validator
|
|
517
|
+
├── elements/ # Paragraph, Run, Table, Image, Hyperlink
|
|
518
|
+
├── formatting/ # Style, NumberingManager
|
|
519
|
+
├── xml/ # XMLBuilder, XMLParser
|
|
520
|
+
├── zip/ # ZipHandler for DOCX manipulation
|
|
521
|
+
└── utils/ # Validation, Units conversion
|
|
577
522
|
|
|
578
523
|
examples/
|
|
579
|
-
├── 01-basic/ #
|
|
580
|
-
├── 02-text/ # Text examples
|
|
524
|
+
├── 01-basic/ # Simple document creation
|
|
525
|
+
├── 02-text/ # Text formatting examples
|
|
581
526
|
├── 03-tables/ # Table examples
|
|
582
527
|
├── 04-styles/ # Style examples
|
|
583
|
-
├── 05-images/ # Image
|
|
584
|
-
|
|
528
|
+
├── 05-images/ # Image handling
|
|
529
|
+
├── 06-complete/ # Full document examples
|
|
530
|
+
└── 07-hyperlinks/ # Link examples
|
|
585
531
|
```
|
|
586
532
|
|
|
587
|
-
##
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
533
|
+
## Hierarchy
|
|
534
|
+
|
|
535
|
+
```text
|
|
536
|
+
w:document (root)
|
|
537
|
+
└── w:body (body container)
|
|
538
|
+
├── w:p (paragraph) [1..n]
|
|
539
|
+
│ ├── w:pPr (paragraph properties) [0..1]
|
|
540
|
+
│ │ ├── w:pStyle (style reference)
|
|
541
|
+
│ │ ├── w:jc (justification/alignment)
|
|
542
|
+
│ │ ├── w:ind (indentation)
|
|
543
|
+
│ │ └── w:spacing (spacing before/after)
|
|
544
|
+
│ ├── w:r (run) [1..n]
|
|
545
|
+
│ │ ├── w:rPr (run properties) [0..1]
|
|
546
|
+
│ │ │ ├── w:b (bold)
|
|
547
|
+
│ │ │ ├── w:i (italic)
|
|
548
|
+
│ │ │ ├── w:u (underline)
|
|
549
|
+
│ │ │ ├── w:sz (font size)
|
|
550
|
+
│ │ │ └── w:color (text color)
|
|
551
|
+
│ │ └── w:t (text content) [1]
|
|
552
|
+
│ ├── w:hyperlink (hyperlink) [0..n]
|
|
553
|
+
│ │ └── w:r (run with hyperlink text)
|
|
554
|
+
│ └── w:drawing (embedded image/shape) [0..n]
|
|
555
|
+
├── w:tbl (table) [1..n]
|
|
556
|
+
│ ├── w:tblPr (table properties)
|
|
557
|
+
│ └── w:tr (table row) [1..n]
|
|
558
|
+
│ └── w:tc (table cell) [1..n]
|
|
559
|
+
│ └── w:p (paragraph in cell)
|
|
560
|
+
└── w:sectPr (section properties) [1] (must be last child of w:body)
|
|
561
|
+
```
|
|
598
562
|
|
|
599
563
|
## Requirements
|
|
600
564
|
|
|
601
|
-
- Node.js
|
|
565
|
+
- Node.js 16+
|
|
602
566
|
- TypeScript 5.0+ (for development)
|
|
603
567
|
|
|
604
|
-
##
|
|
568
|
+
## Installation Options
|
|
605
569
|
|
|
606
|
-
|
|
570
|
+
```bash
|
|
571
|
+
# NPM
|
|
572
|
+
npm install docxmlater
|
|
607
573
|
|
|
608
|
-
|
|
574
|
+
# Yarn
|
|
575
|
+
yarn add docxmlater
|
|
609
576
|
|
|
610
|
-
|
|
577
|
+
# PNPM
|
|
578
|
+
pnpm add docxmlater
|
|
579
|
+
```
|
|
611
580
|
|
|
612
581
|
## Contributing
|
|
613
582
|
|
|
614
|
-
Contributions are welcome! Please read [
|
|
583
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md).
|
|
615
584
|
|
|
616
585
|
1. Fork the repository
|
|
617
|
-
2. Create
|
|
618
|
-
3. Commit
|
|
619
|
-
4. Push to
|
|
586
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
587
|
+
3. Commit changes (`git commit -m 'Add amazing feature'`)
|
|
588
|
+
4. Push to branch (`git push origin feature/amazing-feature`)
|
|
620
589
|
5. Open a Pull Request
|
|
621
590
|
|
|
622
|
-
## Testing
|
|
623
|
-
|
|
624
|
-
All features are comprehensively tested:
|
|
625
|
-
|
|
626
|
-
```bash
|
|
627
|
-
# Run all tests
|
|
628
|
-
npm test
|
|
629
|
-
|
|
630
|
-
# Run specific test suite
|
|
631
|
-
npm test -- tests/core/Document.test.ts
|
|
632
|
-
|
|
633
|
-
# Watch mode
|
|
634
|
-
npm run test:watch
|
|
635
|
-
|
|
636
|
-
# Coverage report
|
|
637
|
-
npm run test:coverage
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
**Test Statistics:**
|
|
641
|
-
|
|
642
|
-
- 159 tests passing
|
|
643
|
-
- 4 test suites
|
|
644
|
-
- High code coverage
|
|
645
|
-
- Integration tests included
|
|
646
|
-
|
|
647
591
|
## License
|
|
648
592
|
|
|
649
593
|
MIT © DiaTech
|
|
650
594
|
|
|
651
595
|
## Acknowledgments
|
|
652
596
|
|
|
653
|
-
- Built with [JSZip](https://stuk.github.io/jszip/) for ZIP
|
|
597
|
+
- Built with [JSZip](https://stuk.github.io/jszip/) for ZIP handling
|
|
654
598
|
- Follows [ECMA-376](https://www.ecma-international.org/publications-and-standards/standards/ecma-376/) Office Open XML standard
|
|
655
599
|
- Inspired by [python-docx](https://python-docx.readthedocs.io/) and [docx](https://github.com/dolanmiu/docx)
|
|
656
600
|
|
|
657
601
|
## Support
|
|
658
602
|
|
|
659
|
-
- **Documentation**: [
|
|
660
|
-
- **Examples**: [
|
|
603
|
+
- **Documentation**: [Full Docs](https://github.com/ItMeDiaTech/docXMLater/tree/main/docs)
|
|
604
|
+
- **Examples**: [Example Code](https://github.com/ItMeDiaTech/docXMLater/tree/main/examples)
|
|
661
605
|
- **Issues**: [GitHub Issues](https://github.com/ItMeDiaTech/docXMLater/issues)
|
|
606
|
+
- **Discussions**: [GitHub Discussions](https://github.com/ItMeDiaTech/docXMLater/discussions)
|
|
662
607
|
|
|
663
|
-
##
|
|
664
|
-
|
|
665
|
-
**Phase 3 (Complete):**
|
|
666
|
-
|
|
667
|
-
- [x] Document API
|
|
668
|
-
- [x] Tables with formatting
|
|
669
|
-
- [x] Styles system
|
|
670
|
-
- [x] Lists and numbering
|
|
671
|
-
|
|
672
|
-
**Phase 4 (Complete):**
|
|
673
|
-
|
|
674
|
-
- [x] Images and media
|
|
675
|
-
- [x] Headers and footers
|
|
676
|
-
- [x] Page sections
|
|
677
|
-
- [x] Hyperlinks (**NEW in v0.2.0!**)
|
|
678
|
-
|
|
679
|
-
**Phase 5 (Future):**
|
|
680
|
-
|
|
681
|
-
- [ ] Track changes
|
|
682
|
-
- [ ] Comments
|
|
683
|
-
- [ ] Table of contents
|
|
684
|
-
- [ ] Fields
|
|
685
|
-
|
|
686
|
-
## Related Projects
|
|
608
|
+
## Quick Links
|
|
687
609
|
|
|
688
|
-
-
|
|
689
|
-
-
|
|
690
|
-
-
|
|
610
|
+
- [NPM Package](https://www.npmjs.com/package/docxmlater)
|
|
611
|
+
- [GitHub Repository](https://github.com/ItMeDiaTech/docXMLater)
|
|
612
|
+
- [API Reference](https://github.com/ItMeDiaTech/docXMLater/tree/main/docs/api)
|
|
613
|
+
- [Change Log](https://github.com/ItMeDiaTech/docXMLater/blob/main/CHANGELOG.md)
|
|
691
614
|
|
|
692
615
|
---
|
|
693
616
|
|
|
694
|
-
**Ready to
|
|
617
|
+
**Ready to create amazing Word documents?** Start with our [examples](https://github.com/ItMeDiaTech/docXMLater/tree/main/examples) or dive into the [API Reference](#complete-api-reference) above!
|