Skip to content

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 28 May 22:11
· 14 commits to main since this release

v0.6.0 closes out the entire remaining roadmap — every tracked issue is now done. This release adds three new input formats, true streaming, password protection, and full chart composition, all zero-dependency and built on web-standard APIs.

npm i hucre@0.6.0

✨ Highlights

🔐 Password-protected workbooks (read + write)

Read and write encrypted .xlsx using ECMA-376 Agile encryption (the Excel 2010+ scheme) — on WebCrypto, so it stays zero-dependency everywhere (Node, Deno, Bun, Workers, browsers).

import { writeXlsx, readXlsx } from "hucre"

const encrypted = await writeXlsx({
  sheets: [{ name: "Secret", rows: [["pin", 1234]] }],
  encryption: { password: "hunter2" },
})

const wb = await readXlsx(encrypted, { password: "hunter2" })

Works through every read entry point (read / readObjects / streamXlsxRows); wrong password → DecryptionError, missing password → EncryptedFileError.
#329 (closes #156, #31)

📖 XLSB (binary workbook) read

Read .xlsb — the compact, fast binary Excel format — into the same model as .xlsx. Auto-detected.

import { read, readXlsb } from "hucre"

const wb = await readXlsb(bytes)   // shared strings, RK/float numbers, dates, formulas…
const same = await read(bytes)     // auto-detected

#330 (closes #154, #51)

🗂️ XLS (legacy Excel 97-2003) read

Read legacy .xls (BIFF8 / OLE2) files — for the archives that never went away.

import { read, readXls } from "hucre"

const wb = await readXls(bytes)    // SST (+CONTINUE), RK/MULRK, bools, errors, dates, merges
const same = await read(bytes)     // auto-detected

#331 (closes #153, #30)

🌊 True streaming XLSX reader

streamXlsxRows now accepts a ReadableStream and parses the ZIP front-to-back from local headers, piping the target worksheet straight into the SAX parser — the whole archive is never buffered.

const res = await fetch("https://example.com/huge.xlsx")
for await (const row of streamXlsxRows(res.body!)) {
  console.log(row.index, row.values)
}

#328 (closes #77)

📊 Chart composition through the roundtrip

saveXlsx now serializes model charts (not just preserves originals), so you can clone template charts onto new/copied sheets and save them — copySheetToWorkbook carries charts across workbooks too.

import { openXlsx, getCharts, cloneChart, addChart, writeXlsx } from "hucre"

const template = await openXlsx(templateBytes)
const [lineChart] = getCharts(template)

const dashboard = { name: "Dashboard", rows: data }
addChart(dashboard, cloneChart(lineChart.chart, {
  title: "Revenue",
  series: [{ name: "Revenue", values: "B2:B13", categories: "A2:A13", color: "1070CA" }],
  anchor: { from: { row: 14, col: 0 } },
}))

await writeXlsx({ sheets: [dashboard] })

#327 (closes #136)

🔗 Inline hyperlinks in data rows

Rich link values can sit directly inside data rows via the link() helper — no parallel cells map needed. #-prefixed targets become internal references.

import { link, writeXlsx } from "hucre"

await writeXlsx({
  sheets: [{
    name: "Links",
    columns: [{ key: "name" }, { key: "site" }],
    data: [
      { name: "Anthropic", site: link("Visit", "https://anthropic.com") },
      { name: "Jump", site: link("Go to Sheet2", "#Sheet2!A1", "internal ref") },
    ],
  }],
})

#326 (closes #325)

Plus chart theme-color refs (schemeClr) and per-host line cap/compound. → #322

⚠️ Notes on the binary / crypto formats

The encryption, XLSB, and XLS code follows the Microsoft specs and is covered by round-trip / builder tests, but hasn't yet been verified against a broad corpus of real Excel-produced files. Treat them as solid-but-new; please file issues with any file that doesn't read cleanly. XLSB/XLS are read-only in this release.

📋 Pull requests in this release

  • #322 — chart theme colors (schemeClr) + line cap/compound
  • #326 — inline hyperlinks in data rows
  • #327 — chart composition through saveXlsx (#136)
  • #328 — true streaming XLSX reader (#77)
  • #329 — password-protected workbooks (#156, #31)
  • #330 — XLSB read (#154, #51)
  • #331 — XLS BIFF8 read (#153, #30)

Full changelog: v0.5.1...v0.6.0