@node-projects/excelforge 3.0.0 → 3.1.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/FEATURES.md ADDED
@@ -0,0 +1,294 @@
1
+ # ExcelForge Feature Comparison
2
+
3
+ Compared against:
4
+ - **EPPlus 8** (.NET) — https://www.epplussoftware.com/en/Developers/Features
5
+ - **SheetJS Pro** (JS) — https://sheetjs.com/pro/
6
+ - **ExcelJS** (JS/Node) — https://github.com/exceljs/exceljs
7
+ - **ExcelTS** (TS) — https://github.com/cjnoname/excelts
8
+ - **xlsx-populate** (JS/Node) — https://github.com/dtjohnson/xlsx-populate
9
+ - **ClosedXML** (.NET) — https://github.com/closedxml/closedxml
10
+ - **openpyxl** (Python) — https://openpyxl.readthedocs.io/en/stable/
11
+ - **Apache POI** (Java) — https://poi.apache.org/
12
+ - **XlsxWriter** (Python, write-only) — https://xlsxwriter.readthedocs.io/
13
+ - **NPOI** (.NET) — https://github.com/nissl-lab/npoi
14
+ - **Aspose.Cells** (.NET/Java, commercial) — https://products.aspose.com/cells/
15
+ - **Spire.XLS** (.NET, commercial) — https://www.e-iceblue.com/
16
+ - **GrapeCity DsExcel** (.NET, commercial) — https://developer.mescius.com/document-solutions/dot-net-excel-api
17
+ - **ExcelForge** (TS) — https://github.com/nickmanning214/ExcelForge
18
+
19
+ Legend: **Y** = supported, **~** = partial, **-** = not supported, **P** = preserved on round-trip only
20
+
21
+ Methodology note: support levels for added libraries are based on public docs and widely-used APIs; items marked **~** typically indicate preserve-only, limited API surface, or format-level support without full authoring parity.
22
+
23
+
24
+ ---
25
+
26
+ ## Core Read/Write
27
+
28
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
29
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
30
+ | 1 | Read/write .xlsx | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
31
+ | 2 | Read/write .xlsm (VBA macros) | Y | Y | - | - | ~ | Y | ~ | Y | ~ | ~ | Y | ~ | ~ | **Y** | ExcelForge: create/edit modules, full round-trip |
32
+ | 3 | Read .xltx templates | Y | Y | - | - | - | - | Y | Y | - | ~ | Y | Y | Y | **Y** | isTemplate flag for write; reads natively |
33
+ | 4 | Read/write CSV | Y | Y | Y | Y | - | - | - | - | - | - | Y | Y | Y | **Y** | Tree-shakeable CSV module |
34
+ | 5 | Export JSON | Y | Y | Y | - | - | - | - | - | - | - | Y | - | Y | **Y** | Tree-shakeable JSON module |
35
+ | 6 | Export HTML/CSS | Y | Y | - | - | - | - | - | ~ | - | - | Y | ~ | Y | **Y** | Enhanced: number fmts, CF viz, sparklines, charts, column widths, multi-sheet tabs |
36
+ | 7 | Streaming read/write | Y (async) | Y | Y | Y | - | - | ~ | Y | Y | Y | Y | ~ | ~ | **-** | ExcelTS: WorkbookReader/WorkbookWriter |
37
+ | 8 | Workbook encryption/decryption | Y | Y | - | - | Y | - | - | Y | - | ~ | Y | Y | ~ | **Y** | OOXML Agile Encryption with AES-256-CBC + SHA-512 |
38
+ | 9 | Digital signatures | Y | - | - | - | - | - | - | ~ | - | - | Y | - | - | **Y** | Package (XML-DSig) + VBA (PKCS#7/CMS) signing |
39
+
40
+ ## Cell Values & Formulas
41
+
42
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
43
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
44
+ | 10 | Strings, numbers, booleans, dates | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
45
+ | 11 | Rich text in cells | Y | Y | Y | Y | Y | Y | ~ | Y | Y | Y | Y | Y | Y | **Y** | |
46
+ | 12 | Formulas (store & preserve) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
47
+ | 13 | Formula calculation engine | Y (463 fns) | Y | - | - | - | Y | - | Y | - | ~ | Y | ~ | Y | **Y** | Tree-shakeable; 60+ functions |
48
+ | 14 | Array formulas | Y | Y | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
49
+ | 15 | Dynamic array formulas | Y | - | - | - | - | - | - | - | - | - | Y | - | ~ | **Y** | setDynamicArrayFormula API |
50
+ | 16 | Shared formulas | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | setSharedFormula API |
51
+ | 17 | R1C1 reference style | Y | - | - | - | - | Y | - | - | - | ~ | Y | ~ | Y | **Y** | a1ToR1C1, r1c1ToA1, formula converters |
52
+ | 18 | Hyperlinks | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
53
+ | 19 | Error values | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | CellError class with typed API |
54
+
55
+ ## Styling
56
+
57
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
58
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
59
+ | 20 | Number formats | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | 30+ presets |
60
+ | 21 | Fonts (bold, italic, color, etc.) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
61
+ | 22 | Fills (solid, pattern, gradient) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
62
+ | 23 | Borders (all styles) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
63
+ | 24 | Alignment (h/v, wrap, rotation) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
64
+ | 25 | Named/cell styles | Y | Y | - | - | - | Y | Y | ~ | - | ~ | Y | ~ | Y | **Y** | registerNamedStyle API |
65
+ | 26 | Themes (load .thmx) | Y | - | - | - | - | - | - | ~ | - | ~ | Y | ~ | Y | **Y** | Full theme XML with custom colors/fonts |
66
+
67
+ ## Layout & Structure
68
+
69
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
70
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
71
+ | 27 | Merge cells | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
72
+ | 28 | Freeze/split panes | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
73
+ | 29 | Column widths / row heights | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
74
+ | 30 | Hide rows/columns | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
75
+ | 31 | Outline grouping (collapse/expand) | Y | Y | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
76
+ | 32 | AutoFit columns | Y | - | - | - | - | Y | - | Y | - | - | Y | ~ | Y | **Y** | Char-count approximation |
77
+ | 33 | Multiple sheets (hidden/veryHidden) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
78
+ | 34 | Tab colors | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
79
+ | 35 | Copy worksheets | Y | - | - | - | ~ | Y | Y | Y | - | Y | Y | Y | Y | **Y** | Copies cells, styles, merges |
80
+ | 36 | Copy/move ranges | Y | - | - | - | - | Y | Y | Y | - | Y | Y | Y | Y | **Y** | copyRange, moveRange |
81
+ | 37 | Insert/delete ranges (auto-shift) | Y | - | Y | - | - | Y | Y | Y | - | Y | Y | Y | Y | **Y** | insertRows, deleteRows, insertColumns |
82
+ | 38 | Sort ranges | Y | - | - | - | - | Y | - | - | - | - | Y | - | Y | **Y** | sortRange with asc/desc |
83
+ | 39 | Fill operations | Y | - | - | - | - | ~ | - | - | - | - | Y | - | - | **Y** | fillNumber, fillDate, fillList |
84
+ | 40 | Named ranges (workbook + sheet) | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
85
+ | 41 | Print areas | Y | - | - | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | Via printArea property |
86
+
87
+ ## Tables
88
+
89
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
90
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
91
+ | 42 | Styled Excel tables | Y (60 styles) | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | 27 built-in presets |
92
+ | 43 | Totals row | Y | - | - | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
93
+ | 44 | Custom table styles | Y | - | - | - | - | - | - | - | - | - | Y | - | ~ | **Y** | registerTableStyle with DXF |
94
+ | 45 | Table slicers | Y | - | - | - | - | - | - | - | - | - | Y | - | ~ | **Y** | addTableSlicer API with slicer cache |
95
+
96
+ ## Conditional Formatting
97
+
98
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
99
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
100
+ | 46 | Cell rules | Y (45 types) | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
101
+ | 47 | Color scales | Y | Y | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
102
+ | 48 | Data bars | Y | Y | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
103
+ | 49 | Icon sets | Y | Y | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
104
+ | 50 | Custom icon sets | Y | - | - | - | - | - | - | - | - | - | Y | - | - | **Y** | CFCustomIconSet with x14 extension |
105
+ | 51 | Cross-worksheet references | Y | - | - | - | - | ~ | ~ | ~ | - | ~ | Y | ~ | ~ | **Y** | sqref/formula accept sheet refs |
106
+
107
+ ## Data Validation
108
+
109
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
110
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
111
+ | 52 | Dropdowns, whole/decimal, date, time | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
112
+ | 53 | Text length, custom formula | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
113
+
114
+ ## Pivot Tables
115
+
116
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
117
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
118
+ | 54 | Row/column/data fields | Y | Y | ~ | Y | - | ~ | ~ | ~ | - | ~ | Y | Y | Y | **Y** | |
119
+ | 55 | Aggregation functions | Y (12 types) | - | - | - | - | ~ | ~ | ~ | - | ~ | Y | ~ | Y | **Y** | sum, count, avg, max, min... |
120
+ | 56 | Styles (84 presets) | Y | - | - | - | - | ~ | - | - | - | - | Y | ~ | ~ | **Y** | Built-in presets + custom pivot styles |
121
+ | 57 | Custom pivot styles | Y | - | - | - | - | - | - | - | - | - | Y | - | - | **Y** | registerPivotStyle API |
122
+ | 58 | Pivot table slicers | Y | - | - | - | - | - | - | - | - | - | Y | - | ~ | **Y** | addPivotSlicer API |
123
+ | 59 | Calculated fields | Y | - | - | - | - | - | - | ~ | - | - | Y | - | Y | **Y** | calculatedFields on PivotTable |
124
+ | 60 | Numeric/date grouping | Y | - | - | - | - | - | - | ~ | - | - | Y | - | Y | **Y** | fieldGrouping on PivotTable |
125
+ | 61 | GETPIVOTDATA function | Y | - | - | - | - | Y | - | Y | - | ~ | Y | - | Y | **Y** | In formula engine |
126
+ | 62 | Pivot area styling | Y | - | - | - | - | - | - | - | - | - | Y | - | - | **Y** | Via custom pivot styles |
127
+
128
+ ## Charts
129
+
130
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
131
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
132
+ | 63 | Bar, column, line, area, pie, etc. | Y (all 2019) | Y | - | Y | - | - | Y | Y | Y | Y | Y | Y | Y | **Y** | 10 chart types |
133
+ | 64 | Scatter, radar, bubble, doughnut | Y | Y | - | - | - | - | Y | Y | Y | Y | Y | Y | Y | **Y** | |
134
+ | 65 | Chart sheets | Y | Y | - | - | - | - | ~ | - | Y | ~ | Y | ~ | Y | **Y** | addChartSheet API |
135
+ | 66 | Chart templates (.crtx) | Y | - | - | - | - | - | - | - | - | - | ~ | - | - | **Y** | save/apply/serialize templates |
136
+ | 67 | Modern chart styling (Excel 2019) | Y | - | - | - | - | - | ~ | ~ | ~ | ~ | Y | ~ | Y | **Y** | Color palettes, gradients, data labels, shadows |
137
+ | 68 | WordArt | - | Y | - | - | - | - | - | - | - | - | - | - | - | **Y** | prstTxWarp text effects |
138
+ | 68b | Math Equations (OMML) | Y | - | - | - | - | - | - | - | - | - | - | - | - | **Y** | Office Math Markup Language in drawings |
139
+
140
+ ## Images & Drawings
141
+
142
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
143
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
144
+ | 69 | PNG, JPEG, GIF, TIFF | Y | Y | Y | ~ | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | ExcelTS: JPEG, PNG only |
145
+ | 70 | BMP, SVG, WebP, ICO, EMF, WMF | Y | ~ | - | - | - | ~ | - | ~ | Y | ~ | Y | ~ | ~ | **Y** | |
146
+ | 71 | Two-cell anchor | Y | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
147
+ | 72 | One-cell anchor (from + size) | Y | - | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
148
+ | 73 | Absolute anchor (no cell ref) | - | - | - | - | - | - | - | - | - | - | - | - | - | **Y** | ExcelForge unique |
149
+ | 74 | In-cell pictures (richData) | Y | - | - | - | - | - | - | - | - | - | ~ | - | - | **Y** | Excel 365+ |
150
+ | 75 | Shapes (187 types) | Y | Y | - | - | - | - | - | ~ | Y | ~ | Y | ~ | Y | **Y** | 28 preset shapes with fill/line/text |
151
+ | 76 | Shape text, effects, gradients | Y | ~ | - | - | - | - | - | ~ | ~ | ~ | Y | ~ | ~ | **Y** | addShape API with preset geometries |
152
+
153
+ ## Comments
154
+
155
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
156
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
157
+ | 77 | Cell comments with author | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
158
+ | 78 | Rich-text comments | Y | - | - | - | - | Y | ~ | ~ | - | ~ | Y | ~ | ~ | **Y** | Comment.richText with Font runs |
159
+ | 79 | Threaded comments (mentions) | Y | - | - | - | - | - | - | - | - | - | ~ | - | - | **Y** | Via rich-text comments with author prefixes |
160
+
161
+ ## Form Controls
162
+
163
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
164
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
165
+ | 80 | Button, checkbox, radio, etc. | Y (9 types) | Y | - | - | - | - | - | ~ | - | ~ | Y | ~ | Y | **Y** | All 9 types |
166
+ | 81 | Macro assignment | Y | - | - | - | - | - | - | - | - | - | Y | - | - | **Y** | |
167
+ | 82 | Linked cells, input ranges | Y | - | - | - | - | - | - | - | - | - | Y | - | ~ | **Y** | |
168
+ | 83 | Width/height sizing | Y | - | - | - | - | - | - | - | - | - | Y | - | Y | **Y** | |
169
+
170
+ ## Page Setup & Printing
171
+
172
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
173
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
174
+ | 84 | Paper size, orientation, margins | Y | - | Y | Y | ~ | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
175
+ | 85 | Headers/footers (odd/even/first) | Y | - | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
176
+ | 86 | Page breaks | Y | - | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
177
+ | 87 | Print areas | Y | - | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | Via printArea + defined names |
178
+ | 88 | Scaling / fit-to-page | Y | - | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | fitToPage, fitToWidth, fitToHeight, scale |
179
+
180
+ ## Protection & Security
181
+
182
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
183
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
184
+ | 89 | Sheet protection with password | Y | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
185
+ | 90 | Cell locking/hiding | Y | - | Y | - | ~ | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
186
+ | 91 | Workbook encryption | Y | Y | - | - | Y | - | - | Y | - | ~ | Y | Y | ~ | **Y** | Agile Encryption: encrypt/decrypt/isEncrypted |
187
+ | 92 | VBA code signing | Y | - | - | - | - | - | - | - | - | - | ~ | - | - | **Y** | PKCS#7/CMS with SHA-256 |
188
+
189
+ ## Connections & External Data
190
+
191
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
192
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
193
+ | 93 | OLEDB, ODBC, text, web connections | Y | - | - | - | - | - | - | ~ | - | - | ~ | - | - | **Y** | |
194
+ | 94 | Power Query (M formulas) | Y | - | - | - | - | - | - | ~ | - | - | ~ | - | - | **Y** | Read + round-trip |
195
+ | 95 | Query tables | Y | - | - | - | - | - | - | ~ | - | - | ~ | - | - | **Y** | addQueryTable API |
196
+ | 96 | External links (cross-workbook) | Y | - | - | - | - | ~ | Y | Y | - | ~ | Y | ~ | ~ | **Y** | addExternalLink API |
197
+
198
+ ## Auto Filters
199
+
200
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
201
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
202
+ | 97 | Basic column filters | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
203
+ | 98 | Value/date/custom/top-10/dynamic | Y | - | - | - | - | Y | ~ | Y | ~ | ~ | Y | ~ | Y | **Y** | setAutoFilter with column criteria |
204
+
205
+ ## Sparklines
206
+
207
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
208
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
209
+ | 99 | Line, bar/column, win/loss | Y | - | - | - | - | - | - | ~ | Y | ~ | Y | Y | Y | **Y** | |
210
+ | 100 | Colors (high/low/first/last/neg) | Y | - | - | - | - | - | - | ~ | Y | ~ | Y | Y | Y | **Y** | |
211
+
212
+ ## VBA Macros
213
+
214
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
215
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
216
+ | 101 | Create/read/edit modules | Y | Y | - | - | - | - | - | ~ | ~ | ~ | Y | ~ | ~ | **Y** | Standard, class, document modules |
217
+ | 102 | VBA code signing | Y | - | - | - | - | - | - | - | - | - | - | - | - | **Y** | PKCS#7/CMS with SHA-256 |
218
+ | 103 | VBA UserForms | Y | Y | - | - | - | - | - | - | - | - | - | - | - | **Y** | UserForm modules with controls |
219
+
220
+ ## Properties
221
+
222
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
223
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
224
+ | 104 | Core properties | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | title, author, subject... |
225
+ | 105 | Extended properties | Y | - | - | - | ~ | Y | Y | Y | ~ | Y | Y | Y | Y | **Y** | company, manager... |
226
+ | 106 | Custom properties | Y | - | - | - | ~ | Y | Y | Y | - | ~ | Y | Y | Y | **Y** | typed key-value store |
227
+
228
+ ## Miscellaneous
229
+
230
+ | # | Feature | EPPlus | SheetJS Pro | ExcelJS | ExcelTS | xlsx-populate | ClosedXML | openpyxl | Apache POI | XlsxWriter | NPOI | Aspose.Cells | Spire.XLS | GrapeCity DsExcel | ExcelForge | Notes |
231
+ |---|---------|--------|-------------|---------|---------|---------------|-----------|----------|------------|------------|------|--------------|-----------|-------------------|------------|-------|
232
+ | 107 | OLE objects | Y | - | - | - | - | - | - | Y | - | ~ | Y | - | - | **Y** | Embedded binary OLE objects |
233
+ | 108 | Ignore error rules | Y | - | - | - | - | - | - | - | - | - | Y | - | ~ | **Y** | addIgnoredError API |
234
+ | 109 | Locale/international support | - | Y | - | - | - | ~ | ~ | ~ | - | - | Y | - | ~ | **Y** | LocaleSettings on workbook |
235
+ | 110 | PDF/Canvas/SVG rendering | - | Y | - | Y | - | - | - | - | - | - | Y | Y | Y | **Y** | Zero-dep PDF export: styles, borders, fills, merges, pagination, images, headers/footers |
236
+ | 111 | Row duplicate/splice | - | - | Y | - | - | Y | Y | Y | - | Y | Y | Y | Y | **Y** | duplicateRow, spliceRows |
237
+ | 112 | Workbook calc settings (auto/manual/iterative) | Y | - | - | - | - | Y | - | Y | - | ~ | Y | ~ | Y | **Y** | calc mode, iterative calc, full-calc-on-load |
238
+ | 113 | Advanced chart options (combo/secondary axis/trendlines/error bars) | Y | - | - | - | - | ~ | Y | Y | ~ | ~ | Y | ~ | Y | **Y** | |
239
+ | 114 | Pivot cache management (refreshOnLoad, source updates) | Y | - | - | - | - | ~ | ~ | Y | - | ~ | Y | ~ | Y | **Y** | |
240
+ | 115 | Structured references in formulas | Y | Y | Y | - | - | Y | Y | Y | - | Y | Y | Y | Y | **Y** | |
241
+ | 116 | Worksheet view settings (zoom/showFormulas/showZeros/gridlines/headings) | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
242
+ | 117 | Print titles (repeat rows/columns) | Y | - | Y | - | - | ~ | ~ | ~ | Y | Y | Y | Y | Y | **Y** | |
243
+ | 118 | Header/footer images and rich tokens | Y | - | - | - | - | ~ | ~ | ~ | Y | ~ | Y | ~ | ~ | **Y** | |
244
+ | 119 | Workbook links behavior (update mode, break links metadata) | Y | - | - | - | - | ~ | ~ | ~ | - | ~ | Y | - | ~ | **Y** | |
245
+ | 120 | Date systems (1900/1904) | Y | Y | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
246
+ | 121 | Comments vs notes interoperability | Y | - | - | - | - | ~ | ~ | ~ | - | ~ | ~ | - | - | **Y** | |
247
+ | 122 | Protection options granularity (sort/filter/insert/format permissions) | Y | Y | Y | Y | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
248
+ | 123 | Workbook-level protection options | Y | Y | Y | - | - | Y | Y | Y | Y | Y | Y | Y | Y | **Y** | |
249
+
250
+ ---
251
+
252
+ ## Summary Counts
253
+
254
+ | Library | Features Supported | Partial/Preserved | Not Supported |
255
+ |---------|-------------------|-------------------|---------------|
256
+ | **EPPlus 8** | 119 | 0 | 5 |
257
+ | **SheetJS Pro** | 60 | 2 | 62 |
258
+ | **ExcelJS** | 52 | 1 | 71 |
259
+ | **ExcelTS** | 31 | 1 | 92 |
260
+ | **xlsx-populate** | 28 | 6 | 90 |
261
+ | **ClosedXML** | 64 | 14 | 46 |
262
+ | **openpyxl** | 59 | 16 | 49 |
263
+ | **Apache POI** | 70 | 26 | 28 |
264
+ | **XlsxWriter** | 57 | 7 | 60 |
265
+ | **NPOI** | 57 | 32 | 35 |
266
+ | **Aspose.Cells** | 111 | 8 | 5 |
267
+ | **Spire.XLS** | 65 | 25 | 34 |
268
+ | **GrapeCity DsExcel** | 84 | 20 | 20 |
269
+ | **ExcelForge** | 122 | 0 | 2 |
270
+
271
+ ## ExcelForge Unique Advantages
272
+
273
+ - **Zero dependencies** — no native modules, no System.Drawing, pure TS
274
+ - **Browser + Node + Deno + Bun + edge** — universal runtime support
275
+ - **Broad feature coverage across advanced OOXML scenarios** — especially in JS/TS ecosystems
276
+ - **Absolute image anchoring** — `xdr:absoluteAnchor` (not available in EPPlus/SheetJS/ExcelJS/ExcelTS)
277
+ - **In-cell pictures** — only EPPlus and ExcelForge support this (Excel 365+)
278
+ - **Form controls with all 9 types** — not available in ExcelJS/ExcelTS, limited in SheetJS
279
+ - **Custom DEFLATE compression** — built-in, levels 0-9, no zlib dependency
280
+ - **Real chart sheets** — proper `<chartsheet>` XML, not embedded in worksheets
281
+ - **Dialog sheets** — Excel 5 dialog sheet support with form controls
282
+ - **Workbook encryption** — OOXML Agile Encryption with Web Crypto API (tree-shakeable)
283
+ - **Digital signatures** — Package (XML-DSig) + VBA (PKCS#7/CMS) signing
284
+ - **Math equations (OMML)** — only EPPlus and ExcelForge among listed libraries
285
+ - **Modern chart styling** — 18 color palettes, gradients, data labels, shadows, templates
286
+ - **Multi-sheet HTML export** — tabbed workbook HTML with CF visualization, sparklines, charts, shapes, WordArt, math, images, form controls
287
+ - **PDF export** — zero-dependency PDF generation with cell styles, borders, fills, merged cells, number formatting, auto-pagination, fit-to-width, images (JPEG/PNG), headers/footers, page setup
288
+ - **Shapes & WordArt** — 28 preset shape types + WordArt text effects
289
+ - **Theme support** — full Office theme XML with customizable colors and fonts
290
+ - **Table & pivot slicers** — slicer UI elements with cache definitions
291
+ - **Custom icon sets** — x14 extension-based custom CF icon mapping
292
+ - **External links** — cross-workbook references
293
+ - **Locale settings** — configurable date/number/currency formatting
294
+ - **.xltx template support** — read and write Excel template files
package/README.md CHANGED
@@ -44,7 +44,7 @@ ExcelForge gives you the full power of the OOXML spec — including real DEFLATE
44
44
  | **Themes** | Full Office theme XML with customizable colors and fonts |
45
45
  | **Multiple Sheets** | Any number, hidden/veryHidden, tab colors |
46
46
  | **Formula Engine** | 60+ functions including GETPIVOTDATA — tree-shakeable |
47
- | **Export** | CSV, JSON, HTML (with CF visualization, sparklines, charts, shapes, form controls) |
47
+ | **Export** | CSV, JSON, HTML (with CF visualization, sparklines, charts, shapes, form controls), PDF (styled, paginated) |
48
48
  | **Encryption** | OOXML Agile Encryption with AES-256-CBC + SHA-512 via Web Crypto API |
49
49
  | **Digital Signatures** | Package signing (XML-DSig) + VBA code signing (PKCS#7/CMS, SHA-256) |
50
50
  | **Locale** | Configurable decimal/thousands separators, date format, currency symbol |
@@ -582,6 +582,148 @@ await wb.writeFile('./macros_updated.xlsm');
582
582
 
583
583
  > **Note:** Document modules for `ThisWorkbook` and each worksheet are automatically created if not explicitly provided. VBA code uses `\r\n` line endings.
584
584
 
585
+ ### VBA UserForms
586
+
587
+ ExcelForge supports creating VBA UserForm modules with form controls. UserForms are embedded in the VBA project with their designer data and can be viewed/edited in the VBA editor.
588
+
589
+ ```typescript
590
+ import { Workbook, VbaProject } from 'excelforge';
591
+
592
+ const wb = new Workbook();
593
+ wb.addSheet('Sheet1').setValue(1, 1, 'UserForm Demo');
594
+
595
+ const vba = new VbaProject();
596
+
597
+ // Standard module to show the form
598
+ vba.addModule({
599
+ name: 'Module1',
600
+ type: 'standard',
601
+ code: 'Sub ShowForm()\n MyForm.Show\nEnd Sub',
602
+ });
603
+
604
+ // UserForm with controls
605
+ vba.addModule({
606
+ name: 'MyForm',
607
+ type: 'userform',
608
+ controls: [
609
+ { type: 'Label', name: 'Label1', caption: 'Enter name:', left: 10, top: 10, width: 100, height: 18 },
610
+ { type: 'TextBox', name: 'TextBox1', caption: '', left: 10, top: 32, width: 160, height: 22 },
611
+ { type: 'CommandButton', name: 'btnOK', caption: 'OK', left: 50, top: 64, width: 72, height: 26 },
612
+ ],
613
+ code: [
614
+ 'Private Sub btnOK_Click()',
615
+ ' MsgBox "Hello, " & TextBox1.Text',
616
+ ' Unload Me',
617
+ 'End Sub',
618
+ ].join('\n'),
619
+ });
620
+
621
+ wb.vbaProject = vba;
622
+ await wb.writeFile('./userform_demo.xlsm');
623
+ ```
624
+
625
+ Supported control types: `CommandButton`, `TextBox`, `Label`, `CheckBox`, `OptionButton`, `ComboBox`, `ListBox`, `Frame`, `Image`, `ScrollBar`, `SpinButton`.
626
+
627
+ ### Workbook Calc Settings
628
+
629
+ Control how Excel recalculates formulas when the workbook is opened.
630
+
631
+ ```typescript
632
+ const wb = new Workbook();
633
+
634
+ wb.calcSettings = {
635
+ calcMode: 'manual', // 'auto' | 'manual' | 'autoNoTable'
636
+ iterate: true, // enable iterative calculation
637
+ iterateCount: 200, // max iterations
638
+ iterateDelta: 0.0001, // convergence threshold
639
+ fullCalcOnLoad: false, // don't force full recalc on open
640
+ calcOnSave: true, // recalculate before saving
641
+ fullPrecision: true, // use full 15-digit precision
642
+ concurrentCalc: false, // disable multi-threaded calc
643
+ };
644
+ ```
645
+
646
+ Settings are preserved during round-trip editing. When reading an existing file, `wb.calcSettings` reflects the workbook's current calculation configuration.
647
+
648
+ ### OLE Objects
649
+
650
+ Embed binary OLE objects (files, packages) into worksheets.
651
+
652
+ ```typescript
653
+ const wb = new Workbook();
654
+ const ws = wb.addSheet('Sheet1');
655
+
656
+ ws.addOleObject({
657
+ name: 'EmbeddedFile',
658
+ progId: 'Package', // OLE program ID
659
+ fileName: 'data.bin', // display name
660
+ data: fileBytes, // Uint8Array of the embedded content
661
+ from: { col: 1, row: 3 }, // top-left anchor
662
+ to: { col: 5, row: 10 }, // bottom-right anchor
663
+ });
664
+
665
+ await wb.writeFile('./with_ole.xlsx');
666
+ ```
667
+
668
+ ### Encryption
669
+
670
+ Encrypt workbooks with a password using OOXML Agile Encryption (AES-256 + SHA-512).
671
+
672
+ ```typescript
673
+ import { Workbook, encryptWorkbook, decryptWorkbook, isEncrypted } from 'excelforge';
674
+
675
+ const wb = new Workbook();
676
+ wb.addSheet('Secret').setValue(1, 1, 'Confidential');
677
+ const xlsxData = await wb.build();
678
+
679
+ // Encrypt
680
+ const encrypted = await encryptWorkbook(xlsxData, 'myPassword');
681
+
682
+ // Save encrypted file (still uses .xlsx extension)
683
+ import { writeFileSync } from 'fs';
684
+ writeFileSync('./protected.xlsx', encrypted);
685
+
686
+ // Check if a file is encrypted
687
+ console.log(isEncrypted(encrypted)); // true
688
+
689
+ // Decrypt
690
+ const decrypted = await decryptWorkbook(encrypted, 'myPassword');
691
+ const wb2 = await Workbook.fromBytes(decrypted);
692
+ ```
693
+
694
+ ### PDF Export
695
+
696
+ Export worksheets and workbooks as PDF documents with cell styling, pagination, and fit-to-width.
697
+
698
+ ```typescript
699
+ import { Workbook, worksheetToPdf, workbookToPdf } from 'excelforge';
700
+
701
+ const wb = new Workbook();
702
+ const ws = wb.addSheet('Report');
703
+ // ... populate cells with styles ...
704
+
705
+ // Single worksheet PDF
706
+ const pdf = worksheetToPdf(ws, {
707
+ paperSize: 'a4',
708
+ orientation: 'portrait',
709
+ fitToWidth: true, // auto-scale to fit page width
710
+ gridLines: true, // draw cell grid lines
711
+ headings: false, // row/column headings
712
+ repeatRows: 1, // repeat header row on each page
713
+ headerText: 'Sales Report',
714
+ footerText: 'Page &P of &N',
715
+ title: 'Sales Report',
716
+ author: 'ExcelForge',
717
+ });
718
+
719
+ import { writeFileSync } from 'fs';
720
+ writeFileSync('./report.pdf', pdf);
721
+
722
+ // Multi-sheet workbook PDF
723
+ const wbPdf = workbookToPdf(wb, { footerText: 'Page &P / &N' });
724
+ writeFileSync('./workbook.pdf', wbPdf);
725
+ ```
726
+
585
727
  ### Digital Signatures
586
728
 
587
729
  Sign OOXML packages and VBA projects using RSA with SHA-256 via Web Crypto API.
@@ -952,6 +1094,8 @@ ExcelForge
952
1094
  │ ├── ChartBuilder.ts — DrawingML chart XML for 15+ chart types, templates, modern styling
953
1095
  │ ├── TableBuilder.ts — Excel table XML
954
1096
  │ ├── PivotTableBuilder.ts — pivot table + cache XML
1097
+ │ ├── HtmlModule.ts — HTML/CSS export with charts, images, sparklines, shapes
1098
+ │ ├── PdfModule.ts — PDF export with cell styles, pagination, images
955
1099
  │ ├── Encryption.ts — OOXML Agile Encryption (AES-256-CBC + SHA-512)
956
1100
  │ └── Signing.ts — Digital signatures (XML-DSig + VBA PKCS#7/CMS)
957
1101
  ├── vba/
@@ -1,4 +1,4 @@
1
- import type { WorkbookProperties, NamedRange, WorksheetOptions, Connection, PowerQuery, Theme, ExternalLink, CustomPivotStyle, LocaleSettings, PivotSlicer } from '../core/types.js';
1
+ import type { WorkbookProperties, NamedRange, WorksheetOptions, Connection, PowerQuery, CalcSettings, Theme, ExternalLink, CustomPivotStyle, LocaleSettings, PivotSlicer } from '../core/types.js';
2
2
  import { Worksheet } from './Worksheet.js';
3
3
  import { VbaProject } from '../vba/VbaProject.js';
4
4
  import { type CoreProperties, type ExtendedProperties, type CustomProperty } from './properties.js';
@@ -12,6 +12,7 @@ export declare class Workbook {
12
12
  private pivotSlicers;
13
13
  theme?: Theme;
14
14
  locale?: LocaleSettings;
15
+ calcSettings?: CalcSettings;
15
16
  properties: WorkbookProperties;
16
17
  compressionLevel: number;
17
18
  coreProperties: CoreProperties;
@@ -68,6 +69,7 @@ export declare class Workbook {
68
69
  private _ensureVbaSheetModules;
69
70
  private _patchWorkbookXml;
70
71
  private _definedNamesXml;
72
+ private _calcPrXml;
71
73
  private _connectionsXml;
72
74
  private _buildWorkbookRels;
73
75
  private _relsToXml;