Import & export
CSV, TSV, HTML, XML, Markdown, JSON, XLSX, and PDF.
Import
sm.importCsv(text); sm.importTsv(text); sm.importHtml(text);
sm.importMarkdown(text); sm.importXml(text);
sm.importJson((jsonDecode(text) as List).cast<Map<String, dynamic>>());
sm.importXlsx(bytes); // Uint8List
Transform before import (Power-Query lite)
Reshape a JSON payload to the grid's columns with a chainable, non-mutating
pipeline, then importJson the result:
final rows = BCellImportTransform(raw)
.rename({'full_name': 'name'}) // key -> new key
.select(['name', 'age']) // keep only these
.where((r) => (r['age'] as num) >= 18)
.mapColumn('name', (v) => '$v'.trim())
.distinct() // drop duplicate rows
.rows; // also: drop / addColumn / sortBy
sm.importJson(rows);
No joins / grouping / aggregation — heavy transforms belong in the host data layer.
Export
sm.toCsv(); sm.toTsv(); sm.toHtml(); sm.toXml(); sm.toMarkdown();
sm.toJson(); // List<Map> ready for jsonEncode
sm.toXlsx(); // -> List<int> (.xlsx bytes)
sm.toXlsx(formulas: true); // export '=A1+B1' as a real Excel formula
sm.toXlsx(styled: false, merged: false); // plain values only (styles/merges are on)
await sm.toPdf(title: 'People'); // -> PDF bytes
await sm.toPdf(title: 'People', selectionOnly: true); // print area = current range
XLSX carries fidelity by default: bold header, per-column alignment and
wrap-text, and cellStyle fill/font colour (styled), plus colspan/rowspan
as real Excel merges that value-round-trip through importXlsx (merged).
Column widths ride both directions (Excel width units ≈ px/7, clamped to
minWidth on import). With formulas: true, =... cells export as real
Excel formulas and importXlsx maps them back to live =... strings, so
formulas survive the round-trip. Number-format codes don't ride — the
excel package's writer can't emit custom numFmts.
Every other export emits the evaluated value of formula cells (never
the raw = — the XLSX default too), and rich-text/number-format cells
flatten to plain text.