Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Releases: ABCrimson/modern-xlsx

v1.0.0 — Stable Release

07 Mar 01:19
@ABCrimson ABCrimson

Choose a tag to compare

v1.0.0 — Stable Release

First stable release. API frozen, production-ready.

Install

npm install modern-xlsx

Highlights

  • 10 Chart Types — bar, column, line, pie, doughnut, scatter, area, radar, bubble, stock with fluent ChartBuilder API
  • Formula Engine — 54 built-in Excel functions (SUM, VLOOKUP, IF, INDEX/MATCH, etc.)
  • Encryption — Read/write password-protected files (ECMA-376 Standard & Agile AES-256)
  • Pivot Tables — Full read/write with PivotTableBuilder API
  • Threaded Comments — Modern Excel comment threads with reply support
  • Slicers & Timelines — Interactive filtering controls (read/write)
  • Streaming Writer — 100K+ row output with O(unique strings) memory
  • Rich TextRichTextBuilder for inline cell formatting with full roundtrip
  • Image Embedding — PNG/JPEG support in worksheets
  • CLI Toolmodern-xlsx info and modern-xlsx convert
  • Error SystemModernXlsxError with 18 machine-readable error codes

Full Feature Set

Everything SheetJS Pro charges for — free and open source:

Feature modern-xlsx SheetJS CE SheetJS Pro
Cell styling Free No Paid
Data validation Free No Paid
Conditional formatting Free No Paid
Rich text Free No Paid
Charts (10 types) Free No Paid
Pivot tables Free No Paid
Encryption Free No No
Formula engine Free No No
Streaming writer Free No Paid
Image embedding Free No Paid
Excel Tables Free No Paid

Performance

Operation modern-xlsx SheetJS CE Factor
Read 100K rows 472 ms 1,901 ms 4.0x faster
Write 100K (batch) 232 ms 1,950 ms 8.4x faster
Read 10K rows 69 ms 170 ms 2.5x faster

Stats

  • Rust: 424 tests (402 unit + 12 golden + 5 security + 4 bench + 1 doctest)
  • TypeScript: 1,287 tests across 58 files
  • WASM binary: ~2.0 MB (1.1 MB with lite build)
  • Zero runtime dependencies

Links

Assets 2
Loading

v1.0.0-rc.1 — Release Candidate 1

06 Mar 22:19
@ABCrimson ABCrimson

Choose a tag to compare

Pre-release

v1.0.0-rc.1 — Release Candidate 1

API frozen, production-ready feature set. All tests passing.

Highlights

New Features

  • PivotTableBuilder — fluent builder API following the ChartBuilder pattern
  • Auto-Filter Custom FiltersCustomFilterData/CustomFiltersData with full roundtrip
  • Page BreaksPageBreaksData with row/column break parsing, writing, and convenience methods
  • Rich Text CellsCell.richText getter/setter, RichTextBuilder fluent API, full WASM roundtrip
  • Image Embedding — PNG/JPEG support in worksheets
  • Error SystemModernXlsxError class with fromWasmError() parser and 18 machine-readable error codes

Improvements

  • API Audit — naming consistency, parameter types, return types across all public APIs
  • JSDoc Coverage — comprehensive documentation across 11 source files with @example tags
  • README — 5-line quick start, improved onboarding
  • Error Messages — context-rich, actionable errors across Rust core (ZIP, XML, OLE2, cell, style)
  • Expanded Builders — ChartBuilder, StyleBuilder with additional JSDoc and methods

Verification

  • Rust: 424 tests (402 unit + 12 golden + 5 security + 4 bench + 1 doctest), clippy clean
  • TypeScript: 1287 tests across 58 files, typecheck clean
  • WASM binary: ~2.0 MB

Audit Reports

  • API Surface Audit — 6 critical, 7 important, 11 minor findings for post-RC
  • Rust Code Audit — safety (as casts in OLE2), performance (writer rels re-parsing), modernization
  • TypeScript Code Audit — dedup opportunities (wasm-loader), helper extraction, error class consistency

Full Changelog: v0.9.2...v1.0.0-rc.1

Loading

v0.9.2 — Streaming Writer, Pivot/Slicer/Timeline Write APIs

06 Mar 20:16
@ABCrimson ABCrimson

Choose a tag to compare

What's New

Streaming XLSX Writer

  • StreamingXlsxWriter for writing 100K+ row files with O(unique strings) memory
  • Backed by Rust/WASM StreamingWriterCore with incremental ZIP entry writing
  • Methods: create(), startSheet(), writeRow(), setStylesXml(), finish()

Pivot Table / Slicer / Timeline Write APIs

  • Pivot Tables: ws.addPivotTable(), ws.removePivotTable(), wb.addPivotCache(), wb.addPivotCacheRecords()
  • Slicers: ws.addSlicer(), ws.removeSlicer(), wb.addSlicerCache()
  • Timelines: ws.addTimeline(), ws.removeTimeline(), wb.addTimelineCache()
  • New types: PivotCacheDefinitionData, PivotCacheRecordsData, discriminated CacheValue unions

WASM Lite Build

  • Feature-gated encryption for smaller WASM binary via modern-xlsx/lite import

Parser Refactoring

  • worksheet/parser.rs reduced from 2,891 → 2,202 lines
  • 20 extracted helper functions for XML attribute parsing

CLI Modernization

  • Node 24 parseArgs() + async node:fs/promises

Security & Documentation

  • Comprehensive ECMA-376 crypto audit (docs/SECURITY-AUDIT.md)
  • Interactive demo site + 4 example projects (sales report, CSV converter, encrypted payroll, chart dashboard)
  • Deno/Bun compatibility test harnesses
  • CHANGELOG.md with full version history

Verification

  • 406 Rust tests — all passing
  • 1,259 TypeScript tests across 57 files — all passing
  • Clippy clean, TypeScript typecheck clean, Biome lint clean
Loading

v0.9.1 — Performance, Quality & Maintainability Overhaul

06 Mar 19:23
@ABCrimson ABCrimson

Choose a tag to compare

35-Point Improvement Release

Rust Performance

  • ryu crate for 2-6x faster f64 formatting in XML/JSON hot paths
  • Byte-level JSON escaping — scans bytes and batch-copies non-escape slices instead of per-char iteration
  • make_rid() helper with itoa::Buffer — eliminated 21 format!() heap allocations in writer
  • Cow<'static, str> on Relationship fields — zero-allocation for static OOXML constants
  • From<serde_json::Error> for ModernXlsxError — 16 .map_err() calls replaced with plain ?
  • if-let chains (Rust 2024 edition idiom)

Rust Code Organization

  • Split worksheet.rs (7,173 lines) → worksheet/{mod,parser,writer,json}.rs
  • Split charts.rs (4,862 lines) → charts/{mod,types,parser,writer}.rs
  • Removed unused serde-wasm-bindgen dependency
  • Added --vacuous-drops to wasm-opt flags

TypeScript Performance & Quality

  • Split barcode.ts (1,828 lines) → 11 tree-shakeable codec modules
  • O(1) sheet name cache via Map<string, number> in Workbook
  • Discriminated union types for Worker messages (type-safe exhaustive switching)
  • Replaced custom at() helpers with native methods
  • Eliminated production as type casts
  • Vitest pool: forksthreads (faster test execution)

CI/CD

  • Security scanning: cargo-audit + npm audit in every CI run
  • WASM binary size tracking with >2MB warning threshold
  • Matrix testing: Node 24 + 25 ×ばつ ubuntu + windows (4 combinations)
  • WASM artifact caching keyed on Cargo.lock + Rust sources

GitHub Presence

  • Added dependabot.yml (Cargo + npm + GitHub Actions, weekly)
  • Added CODEOWNERS, FUNDING.yml
  • Fixed documentation: test counts, Rust version, SECURITY.md version table
  • Added v0.9.0 feature documentation (pivot tables, threaded comments, slicers, timelines, CLI)

Verification

  • 389 Rust tests — all passing, clippy clean (0 warnings)
  • 1,230 TypeScript tests — all passing across 55 test files
  • TypeScript typecheck: 0 errors
  • Biome lint: 0 errors

Full Changelog: v0.9.0...v0.9.1

Loading

v0.9.0 — Pivot Tables, Threaded Comments, Slicers & Timelines

06 Mar 07:20
@ABCrimson ABCrimson

Choose a tag to compare

What's New

Pivot Tables (read-only)

Full OOXML pivot table parsing — definitions, fields, axes, items, subtotals, cache definitions, and cache records. Access via ws.pivotTables.

Threaded Comments (read + write)

Modern Excel threaded comments with person management. Create new threads with ws.addThreadedComment() and reply with ws.replyToComment().

Slicers (read-only)

Slicer definitions and caches for pivot table filtering. Access via ws.slicers.

Timelines (read-only)

Timeline definitions and caches for date-based pivot filtering. Access via ws.timelines.

CLI Tool

npx modern-xlsx info report.xlsx # sheet names, dimensions, row counts
npx modern-xlsx convert data.xlsx out.json # XLSX → JSON
npx modern-xlsx convert data.xlsx out.csv --sheet 0 --format csv

Performance

  • XML writer buffer pre-allocation for faster writes
  • 4-8x faster than SheetJS for bulk read/write operations
  • Honest benchmarks: SheetJS is faster for cell-by-cell writes and small utility conversions

Feature-Gated WASM

encryption and charts Cargo features — opt out of crypto deps for smaller WASM bundles.

API Improvements

  • ModernXlsxError with .code property for structured error handling
  • Readonly arrays throughout the API
  • ws.dimension and ws.rowCount getters

Codebase Quality

  • Full Rust 1.95 modernization (cold_path(), .find(), #[inline])
  • TypeScript 6.0 patterns (satisfies, type guards)
  • Zero clippy warnings

Stats

  • 389 Rust tests | 1,230 TypeScript tests | 55 test files
  • All passing ✅

Full Changelog: v0.8.6...v0.9.0

Loading

v0.8.6 — Rust 1.95 Modernization

06 Mar 01:27
@ABCrimson ABCrimson

Choose a tag to compare

Rust 1.95 Modernization

Deep Rust modernization targeting Rust 1.95-beta features and idiomatic patterns across all 34 Rust source files (~30,760 lines).

Rust 1.95 Features

  • core::hint::cold_path() on all error/panic branches (23 files) — compiler branch layout optimization
  • rust-version bumped to 1.95.0 in workspace Cargo.toml

Iterator Modernization

  • 58 single-attribute for loops replaced with .find() iterator pattern across all OOXML parsers
  • 3 index-based loops replaced with zip() iteration in reader.rs
  • next_r_id() extracted as method on Relationships — deduplicates closure + inline expression in writer.rs

Performance Annotations

  • #[inline] on 3 hot-path streaming JSON helpers (worksheet.rs)
  • #[inline] on 12 chart enum xml_val() methods (charts.rs)

Code Quality

  • Shared serde helpers (is_false, is_true, default_true) extracted to ooxml/mod.rs — removes 22 lines of duplication across 5 files
  • WASM bridge: parse_workbook() + to_js_err() helpers deduplicate 6 JSON parse patterns

Verification

  • 357 Rust tests pass (340 unit + 12 golden + 5 security)
  • 1210 TypeScript tests pass across 50 test files
  • Zero clippy warnings

Full Changelog: v0.8.5...v0.8.6

Loading

v0.8.5 — Comprehensive Audit & Modernization

05 Mar 13:28
@ABCrimson ABCrimson

Choose a tag to compare

Deep audit across the entire codebase: critical bug fixes, lint cleanup, Rust & TypeScript modernization, and expanded test coverage.

Bug Fixes

  • CRITICAL: Merge image + chart drawing XML to prevent silent data loss when sheets have both images and charts
  • Restore ChartAxis.fontSize with proper <c:txPr> writer/parser
  • Parse oneCellAnchor charts from drawing XML (not just twoCellAnchor)
  • Combo chart roundtrip — parse secondary_chart correctly
  • WASM boundary validation for chart data before crossing to Rust

Rust Modernization

  • Eliminated all panic!() calls in encryption — return Result instead
  • Iterator combinators replace manual loops across charts, styles, tables, theme
  • #[derive(Default)] on 7 builder structs, removing dead new() methods
  • Let-else patterns, Option::take() for zero-clone operations
  • Zero clippy warnings across entire codebase

TypeScript 6.0 Modernization

  • satisfies operator for compile-time validation of constant maps
  • readonly on 16 interface array fields for immutability safety
  • Cached Intl.NumberFormat — 10x faster numeric formatting
  • Single-pass escapeHtml — replaces 4-chained .replaceAll()
  • Worker crash memory leak fix (pending promises rejected on terminate)
  • ??= nullish coalescing assignment throughout
  • Eliminated all 19 noNonNullAssertion lint errors with safe array accessors

Test Coverage

  • Rust: 357 tests (expanded golden tests from 2 to 12 scenarios)
  • TypeScript: 1,210 tests (added chart API, chart type, and roundtrip tests)
  • Total: 1,567 tests

Full Changelog: v0.8.1...v0.8.5

Loading

v0.8.1 — Audit Patch

04 Mar 15:28
@ABCrimson ABCrimson

Choose a tag to compare

Bug fixes from comprehensive v0.8.0 charts audit.

Rust Fixes

  • CRITICAL: <drawing> now emitted before <tableParts> per ECMA-376 CT_Worksheet schema — fixes strict validator rejections when worksheets have both charts and tables
  • CRITICAL: <c:style> now emitted before <c:chart> per CT_ChartSpace schema
  • write_f64_element skips NaN/Infinity values (consistent with write_f64_json fix from v0.5.1)
  • Remove dead ChartAxis.font_size field (was never parsed or written)
  • DataLabelsBuilder::build_and_reset() uses Option::take() for zero-clone operation

TypeScript Fixes

  • buildAxisTitle uses == null instead of !title (preserves empty string titles)
  • Remove ChartAxisData.fontSize (dead field, matches Rust removal)
  • Lint fixes: non-null assertions, formatting, cognitive complexity

Full Changelog: v0.8.0...v0.8.1

Loading

v0.8.0 — Charts & Visualizations

04 Mar 14:55
@ABCrimson ABCrimson

Choose a tag to compare

Charts & Visualizations

modern-xlsx now supports full chart creation, reading, and roundtrip — programmatically generate Excel charts with titles, legends, data labels, trendlines, and more.

New Features

Chart Data Model (0.8.0)

  • 10 chart types: Bar, Column, Line, Pie, Doughnut, Scatter, Area, Radar, Bubble, Stock
  • Full data model: ChartData, ChartSeries, ChartAxis, ChartLegend, DataLabels, ChartAnchor
  • Serde roundtrip between Rust structs and JSON (WASM boundary)

Chart XML Writer (0.8.2–0.8.5)

  • Complete ECMA-376 DrawingML Chart XML generation (c:chartSpace, c:chart, c:plotArea)
  • All chart type elements: c:barChart, c:lineChart, c:pieChart, c:scatterChart, etc.
  • Series with fill/line colors, markers, smooth lines, explosion (pie)
  • Axis configuration: scaling (min/max/log), gridlines, tick marks, number formats, axis titles
  • Chart titles with rich text formatting (bold, font size, color)
  • Data labels: showVal, showCatName, showPercent, number format, leader lines
  • Legend with position (top/bottom/left/right/topRight) and overlay
  • Drawing anchors: xdr:twoCellAnchor with cell coordinates and EMU offsets

Chart Drawing & Packaging (0.8.4)

  • xl/charts/chart{n}.xml ZIP entries with content types
  • xl/drawings/drawing{n}.xml with chart anchors
  • Drawing relationships (_rels) linking charts to drawings
  • Worksheet <drawing r:id="..."/> reference
  • Global chart numbering across sheets

TypeScript ChartBuilder API (0.8.6)

  • Fluent builder: new ChartBuilder('bar').title('Sales').addSeries({...}).legend('bottom').build()
  • Worksheet.addChart(type, configure) callback pattern
  • Worksheet.charts getter, addChartData(), removeChart()
  • Full axis configuration, data labels, scatter/radar styles, doughnut hole size

Chart XML Reader (0.8.7)

  • Full SAX parser for chart XML → ChartData structs
  • Drawing anchor parser for xdr:twoCellAnchor elements
  • resolve_charts() two-step resolution: sheet.rels → drawing → chart
  • Charts transition from opaque preserved_entries to structured typed data

Roundtrip & Style Presets (0.8.8)

  • 7 end-to-end WASM write/read roundtrip tests
  • CHART_STYLE_PALETTES — 8 predefined Excel color palettes
  • getChartStylePalette(styleId) helper

Advanced Features (0.8.9)

  • Trendlines: Linear, Exponential, Logarithmic, Polynomial, Power, Moving Average
  • Error Bars: FixedVal, Percentage, StdDev, StdErr with direction (Both/Plus/Minus)
  • 3D Rotation: rotX, rotY, perspective, right-angle axes
  • Data Table: show data table below chart
  • Combo Charts: secondary chart type + secondary value axis (via secondaryChart field)

Example

import { initWasm, Workbook, ChartBuilder } from 'modern-xlsx';
await initWasm();
const wb = new Workbook();
const ws = wb.addSheet('Sales');
// ... populate data ...
ws.addChart('bar', (b) => {
 b.title('Monthly Revenue', { bold: true, fontSize: 1400 })
 .addSeries({ name: 'Revenue', catRef: 'Sales!$A2ドル:$A13ドル', valRef: 'Sales!$B2ドル:$B13ドル', fillColor: '4472C4' })
 .catAxis({ title: 'Month' })
 .valAxis({ title: 'Amount ($)', majorGridlines: true, numFmt: '#,##0' })
 .legend('bottom')
 .grouping('clustered')
 .anchor({ col: 4, row: 0 }, { col: 14, row: 20 });
});
await wb.toFile('report.xlsx');

Stats

  • Rust: 337 tests (330 unit + 2 golden + 5 security)
  • TypeScript: 1171 tests across 47 files
  • Zero clippy warnings, zero type errors
Loading

v0.7.1 — Audit Patch

04 Mar 08:31
@ABCrimson ABCrimson

Choose a tag to compare

Comprehensive Codebase Audit

Bug fixes, security hardening, and precision improvements discovered through deep audit of every Rust and TypeScript file.

Rust Fixes

  • JSON injection prevention — cell references in the streaming JSON path are now properly escaped via json_escape_to, preventing malformed JSON from adversarial XLSX files
  • Whitespace preservation in SST<t> elements in shared strings now include xml:space="preserve" when values start/end with whitespace, preventing Excel from stripping significant spaces
  • Path traversal defenseresolve_relative_path no longer allows .. segments to escape below the root directory in crafted .rels targets
  • Overflow protection — frozen pane topLeftCell computation uses saturating_add to prevent u32 overflow on adversarial input
  • Writer performance — ZIP entries Vec capacity improved from 6 + sheets to 10 + sheets*3 + preserved, reducing reallocations for complex workbooks

TypeScript Fixes

  • ROUND precisionROUND(1.005, 2) now correctly returns 1.01 (fixed floating-point multiplication issue with epsilon adjustment)
  • ROUND/ROUNDUP/ROUNDDOWN — negative fractional digit arguments now use Math.trunc instead of Math.floor, matching Excel semantics
  • Cross-sheet rangesresolveRange now propagates start.sheet to end.sheet, fixing silent wrong-sheet resolution for formulas like Sheet2!A1:B10
  • Tokenizer — invalid exponents (e.g., 1e+) now backtrack instead of emitting NaN tokens
  • sheetToJson — fixed off-by-one in collectRows that could include a spurious extra row past the data bounds
  • SUMIF/COUNTIF — string criteria comparisons now use localeCompare for consistency with the formula evaluator

Stats

  • 299 Rust tests + 1142 TypeScript tests passing
  • Zero clippy warnings, zero lint errors, zero type errors

Full Changelog

Loading
Previous 1
Previous

AltStyle によって変換されたページ (->オリジナル) /