Skip to content

Latest commit

 

History

History
570 lines (401 loc) · 20.5 KB

File metadata and controls

570 lines (401 loc) · 20.5 KB

Fork Status

This is a temporary fork of exceljs/exceljs maintained by Protobi.

Why This Fork Exists

Upstream exceljs has 100+ open PRs, some over a year old. We needed these fixes for production use, so we:

  1. Adopted well-tested upstream PRs
  2. Added critical pivot table features
  3. Published to npm for community benefit
  4. Submitted all changes back to upstream

** Goal:** Sunset this fork once upstream merges our contributions.

Development Workflow

This repository uses Claude Code to accelerate development and maintenance:

  • Issue Triage & Analysis: Review and investigate bug reports and feature requests
  • Pull Request Evaluation: Assess upstream PRs for adoption into this fork
  • Test Development: Create and maintain unit tests, integration tests, and end-to-end tests
  • Code Implementation: Plan and execute bug fixes, feature additions, and refactoring
  • Release Management: Version bumping, changelog updates, and npm publishing

This AI-assisted workflow enables rapid response to community issues while maintaining code quality through comprehensive test coverage.


Fork Release History

4.4.0-protobi.9 (2026-02-01)

New Feature: Pivot Table & Chart Round-Trip Preservation (#41)

Implements complete round-trip preservation for Excel files containing pivot tables, charts, and drawings. Previously, reading an Excel file with pivot tables/charts and writing it back would result in Excel corruption warnings and loss of pivot table/chart data.

Hybrid Preservation Approach:

  • Stores raw XML for pivot tables, charts, and drawings
  • Extracts minimal metadata (cacheId, relationships) for structural integrity
  • Doesn't attempt to fully model complex Excel structures
  • Enables round-trip without data loss or corruption

What's Preserved:

  1. Pivot Tables:

    • Pivot table definitions (xl/pivotTables/pivotTable*.xml)
    • Cache definitions (xl/pivotCache/pivotCacheDefinition*.xml)
    • Cache records (xl/pivotCache/pivotCacheRecords*.xml)
    • Correct cacheId-to-filename mapping via relationship traversal
  2. Charts:

    • Chart definitions (xl/charts/chart*.xml)
    • Chart styles (xl/charts/style*.xml)
    • Chart colors (xl/charts/colors*.xml)
    • All chart relationships
  3. Drawings:

    • Detects drawings with chart references
    • Preserves as raw XML instead of parsing
    • Regular drawings without charts still parsed normally (for image support)
    • Recreates drawing relationships on write
  4. Row Heights:

    • Preserves x14ac:dyDescent attribute for accurate row height
    • Only outputs customHeight if present in original file
    • Fixes row height discrepancies during round-trip

Implementation Details:

  • 16 files modified, 593 insertions, 40 deletions
  • Added test/test-roundtrip-pivot.js for verification
  • Updated test expectations for dyDescent preservation
  • All required content type declarations added
  • Relationship mappings preserved correctly

Testing:

  • ✅ 884/884 unit tests passing
  • ✅ Round-trip test with real-world pivot table/chart files
  • ✅ Excel opens files without corruption warnings
  • ✅ Pivot tables remain functional after round-trip
  • ✅ Charts display correctly after round-trip

Known Limitations:

  • Write-only pivot table creation still supported (existing functionality)
  • Reading/modifying existing pivot table definitions not yet implemented
  • This implementation enables preservation, not programmatic access
  • Hybrid approach: pivot tables can be created OR preserved, not both simultaneously

Related Issues:

  • Inspired by ExcelTS Issue #41
  • Addresses Excel corruption: "Removed Part: /xl/pivotTables/pivotTable1.xml"
  • Fixes missing content type declarations
  • Resolves row height preservation issues

Commit: 853aa94


4.4.0-protobi.8 (2026-01-31)

New Features

  • Form Control Checkbox support (#31)

    • Implement legacy Form Control checkboxes compatible with Excel 2007+, WPS Office, and LibreOffice
    • Add addFormCheckbox() and getFormCheckboxes() worksheet API
    • Support checked/unchecked state, linked cells, and custom text labels
    • Write-only support (reading not yet implemented)
    • Example: ws.addFormCheckbox('B2:D3', { checked: true, link: 'E2', text: 'Accept terms' })
  • Page fields support for pivot tables (#3021)

    • Add pageFields parameter to pivot table API
    • Enables report filtering in Excel pivot tables
    • Example: ws.addPivotTable({ rows: ['Region'], pageFields: ['Year'] })

Security & Dependency Updates

  • Upgrade archiver to 7.x (#11)
    • Implement Duplex interface in StreamBuf (_read() and _write() methods)
    • Upgrade archiver: ^5.3.2 → ^7.0.1
    • Removes deprecated glob 7.x from production dependencies (now uses glob 10.5.0)
    • Addresses CVE-2025-64756 (glob command injection vulnerability)
    • Addresses CVE-772 (inflight vulnerability via glob→inflight chain)
    • glob 7.x remains only in devDependencies (acceptable)

Testing:

  • ✅ 884/884 unit tests passing
  • ✅ Integration tests passing
  • ✅ End-to-end tests passing
  • ✅ Checkbox functionality verified with archiver 7.x

Pull Requests: Merged to master via issue-31 and issue-11 branches


4.4.0-protobi.7 (2026-01-26)

Bug Fixes

  • Added support for reading Excel files created by HAN CELL (Korean spreadsheet software) (exceljs#3014)
    • Fixed crash when reading files with x: namespace prefix
    • Added null checks for workbook, appProperties, and coreProperties
    • Made parsers lenient with unknown XML tags
  • Fixed data bar conditional formatting crash when using minimal API options (exceljs#3015)
    • Provide default cfvo array: [{ type: "min" }, { type: "max" }]
    • Provide default color: Excel blue #638EC6

Testing:

  • Added integration test with real HAN CELL file
  • Added unit tests for data bar default values
  • All 198 tests passing (2 pre-existing unrelated failures)

Pull Requests: #33, #34, #35, #36


4.4.0-protobi.6 (2025-12-14)

Security Fix

  • Fixed Content Security Policy (CSP) violation in Vite builds (#28)
  • Added npm overrides to force asn1.js@5.4.1 (removes eval usage)
  • Dependency chain: browserifycrypto-browserifybrowserify-signparse-asn1asn1.js
  • Verified zero eval() calls in all browser bundles
  • Browser builds now CSP-compliant for modern build tools (Vite, Webpack 5+)

Testing:

  • All existing tests passing
  • Verified dist bundles contain no eval/runInThisContext calls

Commits: 2f6f8b6, 8d106d5


4.4.0-protobi.5 (2025-12-06)

Security & Dependency Updates

Production Dependencies:

  • archiver: ^5.0.0 → ^5.3.2
  • unzipper: 0.10.11 → 0.12.3

Dev Dependencies (Major Updates):

  • mocha: ^7.2.0 → ^11.7.5 (fixes ReDoS in debug, js-yaml, minimatch)
  • chai-xml: ^0.3.2 → ^0.4.1 (fixes xml2js prototype pollution)
  • got: ^9.0.0 → ^11.8.6 (downgraded from 14 for test compatibility)
  • eslint: ^6.5.1 → ^9.39.1
  • grunt-contrib-jasmine: ^2.2.0 → ^4.0.0
  • prettier-eslint: ^11.0.0 → ^16.4.2
  • prettier-eslint-cli: ^5.0.0 → ^8.0.1

Security Improvements:

  • Reduced npm audit vulnerabilities from 38 → 15
  • All remaining vulnerabilities are in dev/test dependencies only
  • No production code security issues

Testing:

  • ✅ Unit tests: 883 passing, 1 pending
  • ✅ Integration tests: 198 passing
  • ✅ End-to-end tests: 1 passing
  • ✅ Build: Successful
  • ⚠️ Browser tests: Disabled (puppeteer@19 compatibility issues)

Known Limitations:

  • glob@7.x remains in dependency tree (deprecated but no active CVEs)
    • Only affects glob 10.x-11.x CLI (CVE-2025-64756), not 7.x library API
    • Upgrading to archiver 7.x requires StreamBuf refactoring (_read/_write methods)
  • Browser tests disabled via .disable-test-browser (puppeteer hangs)
  • got kept at v11 instead of v14 due to breaking API changes in end-to-end tests

Related Issues:

  • #11 - npm audit vulnerabilities (protobi fork)
  • #2984 - Security vulnerabilities in transitive dependencies (upstream)
  • #3006 - glob 7.x dependency discussion (upstream)

Commits: f8e3e47, 9c0f259, 0d57c7b, 639922f


4.4.0-protobi.4 (2025-11)

Multiple pivot tables support, pivot table count metric, streaming limitations documented.


Status Tracking

✅ Features Already Submitted to Upstream (Waiting for Merge)

Feature/Fix Our Issue Upstream PR Status Date
Pivot table count metric #12 #2885 ⏳ Open Feb 2025
Boolean XML parsing fix #18 #2851 ⏳ Open Nov 2024
ExcelToDate validation #19 #2956 ⏳ Open Aug 2025
DynamicFilter parsing #20 #2973 ⏳ Open Sep 2025
SharedString fix #21 #2915 ⏳ Open Apr 2025
Autofilter undefined guard #22 #2978 ⏳ Open (partial) Sep 2025
Image reuse fix #24 #2876 ⏳ Open Feb 2024
Conditional formatting + hyperlinks corruption fix #25 #2803 ⏳ Open Sep 2024
Conditional formatting stopIfTrue & operators #26 #2736 ⏳ Open Jul 2024

Total: 9 PRs adopted from upstream, waiting for official merge

📝 Fork-Specific Features (Submitted to Upstream)

Feature/Fix Our Issue Upstream PR Status Date
Multiple pivot tables support #5 #2995 ⏳ Open Nov 2025
XML special character escaping #3 #2996 ⏳ Open Nov 2025
Pivot table column width control #8 #2997 ⏳ Open Nov 2025
HAN CELL file support - #3017 ⏳ Open Jan 2026
Data bar conditional formatting defaults - #3018 ⏳ Open Jan 2026

Status: All original contributions submitted, waiting for upstream review

Community Fork Contributions (Adopted & Submitted)

Feature/Fix Our Issue Source Upstream PR Status Date
Table addRow() fix #23 rmartin93/exceljs-fork #2998 ⏳ Open Nov 2025

Status: Adopted from community fork, submitted to upstream

Security & Maintenance

Feature/Fix Our Issue Upstream PR Status
Add package-lock.json #10 - Fork-specific
Run npm audit fix #11 - Fork-specific

Status: Security improvements for our fork deployment


Installation

This Fork (Current)

npm install @protobi/exceljs

Official Package (Future)

Once upstream merges our changes:

npm install exceljs

Migration Plan

When to Switch Back to Official

Monitor these conditions:

  1. Upstream releases version with our features
  2. All critical PRs merged (#2885, #2915, etc.)
  3. Our unique features submitted and merged

How to Switch Back

# 1. Check if official version has our features
npm view exceljs version
# Compare against our version: 4.4.0-protobi.2

# 2. Review official changelog
npm view exceljs --json | jq .versions

# 3. Switch packages
npm uninstall @protobi/exceljs
npm install exceljs

# 4. No code changes needed - API compatible!

Deprecation Process

When upstream catches up, we will:

  1. Add deprecation notice to npm package

    npm deprecate @protobi/exceljs "Use official 'exceljs' package - our changes have been merged upstream"
  2. Update README with migration instructions

  3. Archive repository on GitHub

  4. Final release pointing to official package


Features Exclusive to This Fork

1. Multiple Pivot Tables from Same Source

Why it matters: Upstream only supports one pivot table per workbook. We support multiple pivot tables from the same source data with unique cache IDs.

Code:

// ✅ Works in @protobi/exceljs
// ❌ Crashes in official exceljs

const worksheet1 = workbook.addWorksheet('Data');
worksheet1.addRows([/* data */]);

const worksheet2 = workbook.addWorksheet('Pivot1');
worksheet2.addPivotTable({ sourceSheet: worksheet1, /* ... */ });

const worksheet3 = workbook.addWorksheet('Pivot2');
worksheet3.addPivotTable({ sourceSheet: worksheet1, /* ... */ }); // Works!

Files changed:

  • lib/doc/pivot-table.js - Unique cache IDs per pivot table
  • lib/xlsx/xform/book/workbook-xform.js - Support multiple cache definitions

Upstream status: Ready to submit as PR

2. Pivot Table Count Metric

Why it matters: Count is a fundamental Excel pivot table aggregation. Upstream only supports sum.

Code:

// ✅ Works in @protobi/exceljs
// ❌ Not available in official exceljs (yet)

worksheet.addPivotTable({
  sourceSheet: worksheet1,
  rows: ['Category'],
  columns: ['Region'],
  values: ['Sales'],
  metric: 'count', //  NEW!
});

Files changed:

  • lib/doc/pivot-table.js - Accept count metric
  • lib/xlsx/xform/pivot-table/pivot-table-xform.js - Generate XML with subtotal="count"

Upstream status: PR exists (#2885), adopted here

3. Table addRow() Fix for Templates

Why it matters: Loading Excel files with tables and adding rows to them crashes in official exceljs. This is critical for template-based workflows.

Code:

// ✅ Works in @protobi/exceljs
// ❌ Crashes in official exceljs with "Cannot read properties of undefined (reading 'length')"

const workbook = new Excel.Workbook();
await workbook.xlsx.readFile('template.xlsx');

const worksheet = workbook.getWorksheet('Data');
const table = worksheet.getTable('MyTable');

// Add rows to the loaded table
table.addRow(['New', 'Data', 'Here']); // Works!
table.addRow(['More', 'Data', 'Here']); // Works!

await workbook.xlsx.writeFile('output.xlsx');

What it fixes:

  • "Cannot read properties of undefined (reading 'length')" error
  • Missing worksheet references in loaded tables
  • Table references not expanding dynamically when rows are added
  • Excel filter buttons disappearing after save

Files changed:

  • lib/doc/table.js - Dynamic table reference updates, autoFilterRef handling
  • lib/doc/worksheet.js - Table loading compatibility fixes

Upstream status: Adopted from rmartin93/exceljs-fork, preparing upstream PR

4. Enhanced Bug Fixes

See "Status Tracking" section above for 6 bug fixes adopted from upstream PRs.


API Compatibility

This fork maintains 100% API compatibility with official exceljs.

What this means:

  • ✅ Drop-in replacement: require('exceljs') works identically
  • ✅ All official features work exactly the same
  • ✅ Additional features are opt-in (won't break existing code)
  • ✅ Switching back to official requires zero code changes

Version mapping:

Official exceljs:     4.4.0
This fork:            4.4.0-protobi.2
                      └─┬─┘ └──┬───┘
                        │      └─── Fork version (increments with our changes)
                        └────────── Matches upstream base version

Contributing

For Bug Fixes & Features

Please contribute to upstream exceljs, not this fork!

For Fork-Specific Issues

Only use our repo for:

  • Issues with our specific features (#5, #8)
  • Questions about migration
  • Fork maintenance

Create issue: https://github.com/protobi/exceljs/issues


Testing

This fork passes all upstream tests plus additional tests for our features.

# Run all tests
npm test

# Run pivot table tests specifically
npm run test:integration -- --grep "Pivot Tables"

Test Updates vs Upstream

New Test Files Added:

  • spec/integration/workbook/pivot-tables-with-count.spec.js (78 lines)

    • Tests pivot table with metric: 'count' feature
    • Validates XML generation for count aggregation
  • spec/integration/issues/issue-1804-add-image.spec.js (53 lines)

    • Tests image reuse fix (PR #2876)
    • Validates same image added multiple times maintains correct references

Test Infrastructure Changes:

  • Browser tests disabled (puppeteer compatibility issues with updated dependencies)
  • Dev test dependencies updated: mocha 7→11, chai-xml 0.3→0.4
  • End-to-end tests: got API updated (v9→v11)

Test Results:

  • Unit tests: 883 passing, 1 pending (unchanged from upstream)
  • Integration tests: 198 passing (includes 2 new tests above)
  • End-to-end tests: 1 passing
  • Browser tests: Skipped via .disable-test-browser

Note: Fork maintains all upstream tests + adds specific tests for adopted PR features. No upstream tests were removed or modified.


Release History

4.4.0-protobi.2 (2025-11-07)

Added:

  • Pivot table count metric (upstream PR #2885)
  • 5 bug fixes from upstream PRs

Fixed:

  • Boolean XML attribute parsing (#2851)
  • ExcelToDate validation (#2956)
  • DynamicFilter parsing (#2973)
  • WorkbookReader sharedString resolution (#2915)
  • Autofilter undefined guard (#2978)

Security:

  • Added package-lock.json
  • Ran npm audit fix (reduced vulnerabilities)

4.4.0-protobi.1 (2025-11-06)

Initial fork release:

  • Multiple pivot tables from same source
  • XML special character escaping fixes
  • Column width control for pivot tables

Monitoring Upstream

We actively monitor upstream for:

  1. Our PRs being merged - Track at https://github.com/exceljs/exceljs/pulls
  2. New releases - Watch https://github.com/exceljs/exceljs/releases
  3. Breaking changes - Review changelogs for compatibility

Current watch list:

  • 9 adopted PRs awaiting merge (#2851, #2876, #2915, #2956, #2973, #2978, #2885, #2803, #2736)
  • 3 original PRs awaiting merge (#2995, #2996, #2997)
  • 1 community fork contribution awaiting merge (#2998)
  • Total: 13 PRs watching upstream

Update frequency: Monthly check for upstream progress


Support & Contact

For official exceljs support:


License

This fork maintains the same license as upstream exceljs: MIT

See LICENSE


Last Updated: 2025-11-07 Watching: 13 upstream PRs awaiting review/merge Status: Active maintenance until upstream merge - Continuing to adopt community contributions!