docxmlater 0.4.0 → 0.6.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 +484 -561
- package/dist/core/Document.d.ts +60 -0
- package/dist/core/Document.d.ts.map +1 -1
- package/dist/core/Document.js +526 -4
- package/dist/core/Document.js.map +1 -1
- package/dist/core/DocumentGenerator.d.ts.map +1 -1
- package/dist/core/DocumentGenerator.js +6 -3
- package/dist/core/DocumentGenerator.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 +27 -1
- 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 +45 -0
- package/dist/core/RelationshipManager.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 +96 -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/Footnote.d.ts +34 -0
- package/dist/elements/Footnote.d.ts.map +1 -0
- package/dist/elements/Footnote.js +96 -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/Hyperlink.d.ts +1 -0
- package/dist/elements/Hyperlink.d.ts.map +1 -1
- package/dist/elements/Hyperlink.js +53 -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 +21 -0
- package/dist/elements/Image.js.map +1 -1
- package/dist/elements/Paragraph.d.ts +39 -0
- package/dist/elements/Paragraph.d.ts.map +1 -1
- package/dist/elements/Paragraph.js +81 -25
- package/dist/elements/Paragraph.js.map +1 -1
- package/dist/elements/Run.d.ts +1 -0
- package/dist/elements/Run.d.ts.map +1 -1
- package/dist/elements/Run.js +36 -24
- package/dist/elements/Run.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 +67 -1
- package/dist/elements/Table.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 +65 -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 +89 -0
- 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 +88 -3
- package/dist/utils/validation.js.map +1 -1
- package/package.json +1 -1
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
|
+
```
|
|
51
296
|
|
|
52
|
-
|
|
297
|
+
### Add Formatted Text
|
|
298
|
+
|
|
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");
|
|
318
|
+
import { Image, inchesToEmus } from "docxmlater";
|
|
91
319
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
image.setWidth(inchesToEmus(4), true); // 4 inches wide, maintain aspect ratio
|
|
95
|
-
|
|
96
|
-
// Add image to document
|
|
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
|
-
```
|
|
107
|
-
|
|
108
|
-
### Add Hyperlinks
|
|
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
323
|
```
|
|
131
324
|
|
|
132
|
-
|
|
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:
|
|
209
|
-
|
|
210
|
-
```typescript
|
|
211
|
-
const table = doc.createTable(4, 3);
|
|
212
|
-
|
|
213
|
-
// Format table
|
|
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");
|
|
222
|
-
|
|
223
|
-
// Merge cells
|
|
224
|
-
cell?.setColumnSpan(3); // Span 3 columns
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
### Styles
|
|
228
|
-
|
|
229
|
-
13 built-in styles ready to use:
|
|
335
|
+
### Search and Replace Text
|
|
230
336
|
|
|
231
337
|
```typescript
|
|
232
|
-
//
|
|
233
|
-
doc.
|
|
234
|
-
|
|
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
|
|
338
|
+
// Find all occurrences
|
|
339
|
+
const results = doc.findText("old text", { caseSensitive: true });
|
|
340
|
+
console.log(`Found ${results.length} occurrences`);
|
|
241
341
|
|
|
242
|
-
//
|
|
342
|
+
// Replace all
|
|
343
|
+
const count = doc.replaceText("old text", "new text", { wholeWord: true });
|
|
344
|
+
console.log(`Replaced ${count} occurrences`);
|
|
243
345
|
```
|
|
244
346
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
### Document
|
|
347
|
+
### Load and Modify Existing Document
|
|
248
348
|
|
|
249
349
|
```typescript
|
|
250
|
-
|
|
251
|
-
|
|
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)
|
|
280
|
-
```
|
|
350
|
+
const doc = await Document.load("existing.docx");
|
|
351
|
+
doc.createParagraph("Added paragraph");
|
|
281
352
|
|
|
282
|
-
|
|
353
|
+
// Update all hyperlinks
|
|
354
|
+
const urlMap = new Map([["https://old-site.com", "https://new-site.com"]]);
|
|
355
|
+
doc.updateHyperlinkUrls(urlMap);
|
|
283
356
|
|
|
284
|
-
|
|
285
|
-
// Content
|
|
286
|
-
para.addText(text, formatting?)
|
|
287
|
-
para.addRun(run)
|
|
288
|
-
para.setText(text, formatting?)
|
|
289
|
-
|
|
290
|
-
// Formatting
|
|
291
|
-
para.setAlignment('left' | 'center' | 'right' | 'justify')
|
|
292
|
-
para.setLeftIndent(twips)
|
|
293
|
-
para.setRightIndent(twips)
|
|
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()
|
|
357
|
+
await doc.save("modified.docx");
|
|
305
358
|
```
|
|
306
359
|
|
|
307
|
-
###
|
|
360
|
+
### Create Lists
|
|
308
361
|
|
|
309
362
|
```typescript
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
subscript: true,
|
|
320
|
-
superscript: true,
|
|
321
|
-
smallCaps: true,
|
|
322
|
-
allCaps: true,
|
|
323
|
-
};
|
|
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);
|
|
324
372
|
```
|
|
325
373
|
|
|
326
|
-
###
|
|
374
|
+
### Apply Custom Styles
|
|
327
375
|
|
|
328
376
|
```typescript
|
|
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");
|
|
342
|
-
```
|
|
377
|
+
import { Style } from "docxmlater";
|
|
343
378
|
|
|
344
|
-
|
|
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
|
+
});
|
|
345
386
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
Style.createNormalStyle();
|
|
349
|
-
Style.createHeadingStyle(1 - 9);
|
|
350
|
-
Style.createTitleStyle();
|
|
351
|
-
Style.createSubtitleStyle();
|
|
352
|
-
|
|
353
|
-
// Properties
|
|
354
|
-
style.setBasedOn(styleId);
|
|
355
|
-
style.setParagraphFormatting(formatting);
|
|
356
|
-
style.setRunFormatting(formatting);
|
|
387
|
+
doc.addStyle(customStyle);
|
|
388
|
+
doc.createParagraph("Custom Styled Text").setStyle("CustomHeading");
|
|
357
389
|
```
|
|
358
390
|
|
|
359
|
-
###
|
|
391
|
+
### Add Headers and Footers
|
|
360
392
|
|
|
361
393
|
```typescript
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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);
|
|
377
410
|
```
|
|
378
411
|
|
|
379
|
-
###
|
|
412
|
+
### Work with Document Statistics
|
|
380
413
|
|
|
381
414
|
```typescript
|
|
382
|
-
//
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
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
|
|
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`);
|
|
411
426
|
```
|
|
412
427
|
|
|
413
|
-
|
|
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
|
|
476
|
-
|
|
477
|
-
Run any example:
|
|
478
|
-
|
|
479
|
-
```bash
|
|
480
|
-
npx ts-node examples/02-text/paragraph-basics.ts
|
|
481
|
-
```
|
|
482
|
-
|
|
483
|
-
## Documentation
|
|
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
|
|
428
|
+
### Handle Large Documents Efficiently
|
|
494
429
|
|
|
495
430
|
```typescript
|
|
496
|
-
|
|
497
|
-
|
|
431
|
+
const doc = Document.create({
|
|
432
|
+
maxMemoryUsagePercent: 80,
|
|
433
|
+
maxRssMB: 2048,
|
|
434
|
+
maxImageCount: 50,
|
|
435
|
+
maxTotalImageSizeMB: 100,
|
|
436
|
+
});
|
|
498
437
|
|
|
499
|
-
//
|
|
500
|
-
doc.createParagraph("New paragraph added");
|
|
438
|
+
// Process document...
|
|
501
439
|
|
|
502
|
-
//
|
|
503
|
-
await doc.save("
|
|
440
|
+
// Clean up resources after saving
|
|
441
|
+
await doc.save("large-document.docx");
|
|
442
|
+
doc.dispose(); // Free memory
|
|
504
443
|
```
|
|
505
444
|
|
|
506
|
-
###
|
|
445
|
+
### Direct XML Access (Advanced)
|
|
507
446
|
|
|
508
447
|
```typescript
|
|
509
|
-
//
|
|
510
|
-
const
|
|
511
|
-
|
|
448
|
+
// Get raw XML
|
|
449
|
+
const documentXml = await doc.getPart("word/document.xml");
|
|
450
|
+
console.log(documentXml?.content);
|
|
512
451
|
|
|
513
|
-
//
|
|
514
|
-
|
|
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");
|
|
515
455
|
|
|
516
|
-
//
|
|
517
|
-
const
|
|
456
|
+
// List all parts
|
|
457
|
+
const parts = await doc.listParts();
|
|
458
|
+
console.log("Document contains:", parts.length, "parts");
|
|
518
459
|
```
|
|
519
460
|
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
461
|
+
## 🎯 Features
|
|
462
|
+
|
|
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()`
|
|
488
|
+
|
|
489
|
+
## 🧪 Testing
|
|
526
490
|
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
const xml = handler.getFileAsString(DOCX_PATHS.DOCUMENT);
|
|
532
|
-
handler.updateFile(DOCX_PATHS.DOCUMENT, modifiedXml);
|
|
533
|
-
|
|
534
|
-
await handler.save("output.docx");
|
|
491
|
+
```bash
|
|
492
|
+
npm test # Run all tests
|
|
493
|
+
npm run test:watch # Watch mode
|
|
494
|
+
npm run test:coverage # Coverage report
|
|
535
495
|
```
|
|
536
496
|
|
|
537
|
-
|
|
497
|
+
**Current:** 253 tests passing | 100% core functionality covered
|
|
538
498
|
|
|
539
|
-
|
|
499
|
+
## 🛠 Development
|
|
540
500
|
|
|
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
|
```
|
|
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
|
+
## Heigharch
|
|
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
|
-
## Requirements
|
|
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
|
-
## Contributing
|
|
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
|
-
##
|
|
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
|
-
## License
|
|
591
|
+
## 📄 License
|
|
648
592
|
|
|
649
593
|
MIT © DiaTech
|
|
650
594
|
|
|
651
|
-
## Acknowledgments
|
|
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
|
-
## Support
|
|
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!
|